diff --git a/components/3rd_party/sophgo-middleware/.gitignore b/components/3rd_party/sophgo-middleware/.gitignore new file mode 100644 index 00000000..6ceeedbe --- /dev/null +++ b/components/3rd_party/sophgo-middleware/.gitignore @@ -0,0 +1,2 @@ +!*.so* +!*.a \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/CMakeLists.txt b/components/3rd_party/sophgo-middleware/CMakeLists.txt new file mode 100644 index 00000000..59115dda --- /dev/null +++ b/components/3rd_party/sophgo-middleware/CMakeLists.txt @@ -0,0 +1,69 @@ +set(middleware_src_path "${CMAKE_CURRENT_SOURCE_DIR}/sophgo-middleware") + +# middleware +set(middleware_include_dir . + ${middleware_src_path}/v2/component/panel/sg200x + ${middleware_src_path}/v2/include + ${middleware_src_path}/v2/include/isp/sg200x + ${middleware_src_path}/v2/sample/common + ${middleware_src_path}/v2/uapi + ${middleware_src_path}/v2/3rdparty/inih + ${middleware_src_path}/v2/modules/ive/include/ +) +list(APPEND ADD_INCLUDE ${middleware_include_dir}) +set_property(SOURCE ${middleware_include_dir} PROPERTY GENERATED 1) + +append_srcs_dir(middleware_src_dir ${middleware_src_path}/v2/sample/common + ${middleware_src_path}/v2/component/isp/sensor/cv181x/gcore_gc4653 + ${middleware_src_path}/v2/component/isp/sensor/sg200x/sms_sc035gs + ${middleware_src_path}/v2/component/isp/sensor/sg200x/ov_ov2685 + ) +list(APPEND ADD_SRCS ${middleware_src_dir}) +set_property(SOURCE ${middleware_src_dir} PROPERTY GENERATED 1) + +set(mmf_lib_dir ${middleware_src_path}/v2/lib) +set(middleware_dynamic_lib_file ${mmf_lib_dir}/libcvi_ive.so + ${mmf_lib_dir}/libcvi_bin.so + ${mmf_lib_dir}/libaaccomm2.so + ${mmf_lib_dir}/libaacdec2.so + ${mmf_lib_dir}/libaacenc2.so + ${mmf_lib_dir}/libaacsbrdec2.so + ${mmf_lib_dir}/libaacsbrenc2.so + ${mmf_lib_dir}/libae.so + ${mmf_lib_dir}/libaf.so + ${mmf_lib_dir}/libawb.so + ${mmf_lib_dir}/libcvi_audio.so + ${mmf_lib_dir}/libcvi_bin_isp.so + ${mmf_lib_dir}/libcvi_bin.so + ${mmf_lib_dir}/libcvi_ispd2.so + ${mmf_lib_dir}/libcvi_RES1.so + ${mmf_lib_dir}/libcvi_ssp.so + ${mmf_lib_dir}/libcvi_VoiceEngine.so + ${mmf_lib_dir}/libcvi_vqe.so + ${mmf_lib_dir}/libdnvqe.so + ${mmf_lib_dir}/libisp_algo.so + ${mmf_lib_dir}/libisp.so + ${mmf_lib_dir}/libmipi_tx.so + ${mmf_lib_dir}/libmisc.so + ${mmf_lib_dir}/libosdc.so + ${mmf_lib_dir}/libraw_dump.so + ${mmf_lib_dir}/libsys.so + ${mmf_lib_dir}/libvdec.so + ${mmf_lib_dir}/libvenc.so + ${mmf_lib_dir}/libvpu.so + ${mmf_lib_dir}/libjson-c.so.5 + ${mmf_lib_dir}/libtinyalsa.so + ${mmf_lib_dir}/3rd/libcli.so + ${mmf_lib_dir}/3rd/libini.so) +list(APPEND ADD_DYNAMIC_LIB ${middleware_dynamic_lib_file}) +set_property(SOURCE ${middleware_dynamic_lib_file} PROPERTY GENERATED 1) + +list(APPEND ADD_DEFINITIONS_PRIVATE -DSENSOR_GCORE_GC4653 + -DSENSOR0_TYPE=SONY_IMX327_MIPI_2M_30FPS_12BIT + -DSENSOR1_TYPE=SONY_IMX327_MIPI_2M_30FPS_12BIT) + +list(APPEND ADD_DEFINITIONS_PRIVATE -DSENSOR_SMS_SC035GS + -DSENSOR2_TYPE=SMS_SC035GS_MIPI_480P_120FPS_12BIT) + +list(APPEND ADD_DEFINITIONS_PRIVATE -DSENSOR_OV_OV2685) +register_component(DYNAMIC) \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/Kconfig b/components/3rd_party/sophgo-middleware/Kconfig new file mode 100644 index 00000000..e69de29b diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/Makefile new file mode 100644 index 00000000..0ed1605f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/Makefile @@ -0,0 +1,13 @@ + +all: + @echo "#################################################" + @echo "# #" + @echo "# Compiling '3rdparty libs' Configs as below #" + @echo "# #" + @echo "#################################################" + @for x in `find ./ -maxdepth 2 -mindepth 2 -name "Makefile" `; \ + do cd `dirname $$x`; if [ $$? ]; then make || exit 1; cd -; fi; done + +clean: + @for x in `find ./ -maxdepth 2 -mindepth 2 -name "Makefile" `; \ + do cd `dirname $$x`; if [ $$? ]; then make clean; cd -; fi; done diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/Makefile new file mode 100644 index 00000000..5d311e75 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/Makefile @@ -0,0 +1,19 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) +PARAM_FILE:=../../Makefile.param +include $(PARAM_FILE) +endif + + +PREBUILT_LIB = lib_$(SDK_VER) + +all : + @rm -rf lib + @ln -s $(PREBUILT_LIB) lib + @cp -a include/* $(MW_INC) + @cp -a lib/* $(MW_3RD_LIB) + +clean : + @rm -rf lib + @rm -rf $(MW_INC)/cli.h + @rm -f $(MW_3RD_LIB)/libcli* diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/include/cli.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/include/cli.h new file mode 100644 index 00000000..aa9b2a2d --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/include/cli.h @@ -0,0 +1,96 @@ +#ifndef __CLIAPI_H__ +#define __CLIAPI_H__ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#define CLI_UART_SUPPORT 0x01 +#define CLI_TELNET_SUPPORT 0x02 +#define CLI_UART_CLIENT_SUPPORT 0x04 + + +#define DECLARE_TELNET_CLI_CMD_MACRO(name, child, Cbfunc, help, usermode) { \ +(#name), \ +child, \ +Cbfunc, \ +(#help), \ +usermode, \ +0, \ +0, \ +0 \ +} + +#define DECLARE_TELNET_CLI_CMD_MACRO_END() { \ +(0), \ +(0), \ +(0), \ +(0), \ +(0), \ +(0), \ +(0), \ +(0) \ +} + +typedef enum{ + DEBUG_EN_TRACE_NONE = 0, //always print + DEBUG_EN_TRACE_ERROR, + DEBUG_EN_TRACE_WARNING, + DEBUG_EN_TRACE_INFO, + DEBUG_EN_TRACE_BUTT +} DEBUG_EN_LEVEL; + +typedef struct TELNET_CLI_S_COMMANDtag { + char *pcName; + struct TELNET_CLI_S_COMMANDtag *pChildren; + int (*pCallback)(int argc, char *argv[]); + char *pcCmdHelp; + int i32UserMode; + struct TELNET_CLI_S_COMMANDtag *next; + struct TELNET_CLI_S_COMMANDtag *parent; + struct TELNET_CLI_S_COMMANDtag *prev; +} TELNET_CLI_S_COMMAND, *TELNET_CLI_S_COMMAND_PTR; + +// for_register_cmd +typedef TELNET_CLI_S_COMMAND TELNET_S_CLICMD; + +#define DECLARE_CLI_CMD_MACRO(name, child, Cbfunc, help, usermode) \ + DECLARE_TELNET_CLI_CMD_MACRO(name, child, Cbfunc, help, usermode) + +#define DECLARE_CLI_CMD_MACRO_END() DECLARE_TELNET_CLI_CMD_MACRO_END() +// end for_register_cmd + +extern void TelnetTracePrint(const DEBUG_EN_LEVEL enLevel, char *pcpathname, + const unsigned int u32Line, const char *fmt, ...); +extern int RegisterCliCommand(void *pstCliCmd); +extern void CliInit(int flag); +extern void CliDeInit(void); + + +#ifndef tcli_info +#define tcli_info(fmt...) TelnetTracePrint(DEBUG_EN_TRACE_INFO, __FILE__, __LINE__, fmt) +#endif + +#ifndef tcli_warning +#define tcli_warning(fmt...) TelnetTracePrint(DEBUG_EN_TRACE_WARNING, __FILE__, __LINE__, fmt) +#endif + +#ifndef tcli_error +#define tcli_error(fmt...) TelnetTracePrint(DEBUG_EN_TRACE_ERROR, __FILE__, __LINE__, fmt) +#endif + + +//always print,can not be control +#ifndef tcli_print +#define tcli_print(fmt...) TelnetTracePrint(DEBUG_EN_TRACE_NONE, __FILE__, __LINE__, fmt) +#endif + + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ +#endif diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_32bit/cli b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_32bit/cli new file mode 100644 index 00000000..2353c055 Binary files /dev/null and b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_32bit/cli differ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_32bit/libcli.a b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_32bit/libcli.a new file mode 100644 index 00000000..876824ca Binary files /dev/null and b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_32bit/libcli.a differ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_32bit/libcli.so b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_32bit/libcli.so new file mode 100644 index 00000000..e4a48c74 Binary files /dev/null and b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_32bit/libcli.so differ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_64bit/cli b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_64bit/cli new file mode 100644 index 00000000..c49428ef Binary files /dev/null and b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_64bit/cli differ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_64bit/libcli.a b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_64bit/libcli.a new file mode 100644 index 00000000..c13cf6f8 Binary files /dev/null and b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_64bit/libcli.a differ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_64bit/libcli.so b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_64bit/libcli.so new file mode 100644 index 00000000..b2c0d04b Binary files /dev/null and b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_64bit/libcli.so differ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_musl_riscv64/cli b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_musl_riscv64/cli new file mode 100644 index 00000000..ceb7123d Binary files /dev/null and b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_musl_riscv64/cli differ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_musl_riscv64/libcli.a b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_musl_riscv64/libcli.a new file mode 100644 index 00000000..c4971bbf Binary files /dev/null and b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_musl_riscv64/libcli.a differ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_musl_riscv64/libcli.so b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_musl_riscv64/libcli.so new file mode 100644 index 00000000..abc9aae4 Binary files /dev/null and b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/cli/lib_musl_riscv64/libcli.so differ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/LICENSE.txt b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/LICENSE.txt new file mode 100644 index 00000000..cb7ee2d0 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/LICENSE.txt @@ -0,0 +1,27 @@ + +The "inih" library is distributed under the New BSD license: + +Copyright (c) 2009, Ben Hoyt +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Ben Hoyt nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY BEN HOYT ''AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BEN HOYT BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/Makefile new file mode 100644 index 00000000..3f90acc4 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/Makefile @@ -0,0 +1,38 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE:=../../Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_3RD_LIB)/libini.a +TARGET_SO = $(MW_3RD_LIB)/libini.so + +EXTRA_CFLAGS = $(INCS) + +.PHONY : all +all : $(TARGET_A) $(TARGET_SO) install + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -o $@ -c $< + @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 $@) + +install: + @cp ini.h $(MW_INC) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) $(MW_INC)/ini.h + +-include $(DEPS) diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/README.md b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/README.md new file mode 100644 index 00000000..da5a5671 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/README.md @@ -0,0 +1,152 @@ +# inih (INI Not Invented Here) + +[![TravisCI Build](https://travis-ci.org/benhoyt/inih.svg)](https://travis-ci.org/benhoyt/inih) + +**inih (INI Not Invented Here)** is a simple [.INI file](http://en.wikipedia.org/wiki/INI_file) parser written in C. It's only a couple of pages of code, and it was designed to be _small and simple_, so it's good for embedded systems. It's also more or less compatible with Python's [ConfigParser](http://docs.python.org/library/configparser.html) style of .INI files, including RFC 822-style multi-line syntax and `name: value` entries. + +To use it, just give `ini_parse()` an INI file, and it will call a callback for every `name=value` pair parsed, giving you strings for the section, name, and value. It's done this way ("SAX style") because it works well on low-memory embedded systems, but also because it makes for a KISS implementation. + +You can also call `ini_parse_file()` to parse directly from a `FILE*` object, `ini_parse_string()` to parse data from a string, or `ini_parse_stream()` to parse using a custom fgets-style reader function for custom I/O. + +Download a release, browse the source, or read about [how to use inih in a DRY style](http://blog.brush.co.nz/2009/08/xmacros/) with X-Macros. + + +## Compile-time options ## + +You can control various aspects of inih using preprocessor defines: + +### Syntax options ### + + * **Multi-line entries:** By default, inih supports multi-line entries in the style of Python's ConfigParser. To disable, add `-DINI_ALLOW_MULTILINE=0`. + * **UTF-8 BOM:** By default, inih allows a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of INI files. To disable, add `-DINI_ALLOW_BOM=0`. + * **Inline comments:** By default, inih allows inline comments with the `;` character. To disable, add `-DINI_ALLOW_INLINE_COMMENTS=0`. You can also specify which character(s) start an inline comment using `INI_INLINE_COMMENT_PREFIXES`. + * **Start-of-line comments:** By default, inih allows both `;` and `#` to start a comment at the beginning of a line. You can override this by changing `INI_START_COMMENT_PREFIXES`. + * **Allow no value:** By default, inih treats a name with no value (no `=` or `:` on the line) as an error. To allow names with no values, add `-DINI_ALLOW_NO_VALUE=1`, and inih will call your handler function with value set to NULL. + +### Parsing options ### + + * **Stop on first error:** By default, inih keeps parsing the rest of the file after an error. To stop parsing on the first error, add `-DINI_STOP_ON_FIRST_ERROR=1`. + * **Report line numbers:** By default, the `ini_handler` callback doesn't receive the line number as a parameter. If you need that, add `-DINI_HANDLER_LINENO=1`. + * **Call handler on new section:** By default, inih only calls the handler on each `name=value` pair. To detect new sections (e.g., the INI file has multiple sections with the same name), add `-DINI_CALL_HANDLER_ON_NEW_SECTION=1`. Your handler function will then be called each time a new section is encountered, with `section` set to the new section name but `name` and `value` set to NULL. + +### Memory options ### + + * **Stack vs heap:** By default, inih creates a fixed-sized line buffer on the stack. To allocate on the heap using `malloc` instead, specify `-DINI_USE_STACK=0`. + * **Maximum line length:** The default maximum line length (for stack or heap) is 200 bytes. To override this, add something like `-DINI_MAX_LINE=1000`. Note that `INI_MAX_LINE` must be 3 more than the longest line (due to `\r`, `\n`, and the NUL). + * **Allow realloc:** By default when using the heap (`-DINI_USE_STACK=0`), inih allocates a fixed-sized buffer of `INI_INITIAL_ALLOC` bytes. To allow this to grow to `INI_MAX_LINE` bytes, doubling if needed, set `-DINI_ALLOW_REALLOC=1`. + * **Initial malloc size:** `INI_INITIAL_ALLOC` specifies the initial malloc size when using the heap. It defaults to 200 bytes. + +## Simple example in C ## + +```c +#include +#include +#include +#include "../ini.h" + +typedef struct +{ + int version; + const char* name; + const char* email; +} configuration; + +static int handler(void* user, const char* section, const char* name, + const char* value) +{ + configuration* pconfig = (configuration*)user; + + #define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0 + if (MATCH("protocol", "version")) { + pconfig->version = atoi(value); + } else if (MATCH("user", "name")) { + pconfig->name = strdup(value); + } else if (MATCH("user", "email")) { + pconfig->email = strdup(value); + } else { + return 0; /* unknown section/name, error */ + } + return 1; +} + +int main(int argc, char* argv[]) +{ + configuration config; + + if (ini_parse("test.ini", handler, &config) < 0) { + printf("Can't load 'test.ini'\n"); + return 1; + } + printf("Config loaded from 'test.ini': version=%d, name=%s, email=%s\n", + config.version, config.name, config.email); + return 0; +} +``` + + +## C++ example ## + +If you're into C++ and the STL, there is also an easy-to-use [INIReader class](https://github.com/benhoyt/inih/blob/master/cpp/INIReader.h) that stores values in a `map` and lets you `Get()` them: + +```cpp +#include +#include "INIReader.h" + +int main() +{ + INIReader reader("../examples/test.ini"); + + if (reader.ParseError() < 0) { + std::cout << "Can't load 'test.ini'\n"; + return 1; + } + std::cout << "Config loaded from 'test.ini': version=" + << reader.GetInteger("protocol", "version", -1) << ", name=" + << reader.Get("user", "name", "UNKNOWN") << ", email=" + << reader.Get("user", "email", "UNKNOWN") << ", pi=" + << reader.GetReal("user", "pi", -1) << ", active=" + << reader.GetBoolean("user", "active", true) << "\n"; + return 0; +} +``` + +This simple C++ API works fine, but it's not very fully-fledged. I'm not planning to work more on the C++ API at the moment, so if you want a bit more power (for example `GetSections()` and `GetFields()` functions), see these forks: + + * https://github.com/Blandinium/inih + * https://github.com/OSSystems/inih + + +## Differences from ConfigParser ## + +Some differences between inih and Python's [ConfigParser](http://docs.python.org/library/configparser.html) standard library module: + +* INI name=value pairs given above any section headers are treated as valid items with no section (section name is an empty string). In ConfigParser having no section is an error. +* Line continuations are handled with leading whitespace on continued lines (like ConfigParser). However, instead of concatenating continued lines together, they are treated as separate values for the same key (unlike ConfigParser). + + +## Platform-specific notes ## + +* Windows/Win32 uses UTF-16 filenames natively, so to handle Unicode paths you need to call `_wfopen()` to open a file and then `ini_parse_file()` to parse it; inih does not include `wchar_t` or Unicode handling. + +## Meson notes ## + +* The `meson.build` file is intended to build libraries which can be installed on a system. This is not required to use or compile inih. +* If you want to use inih for programs which may be shipped in a distro, consider linking against the shared library. Meson adds entries for pkg-config (`inih` and `INIReader`). +* In case you use inih as a subproject, you can use the `inih_dep` and `INIReader_dep` dependency variables. + +## Building from vcpkg ## + +You can build and install inih using [vcpkg](https://github.com/microsoft/vcpkg/) dependency manager: + + git clone https://github.com/Microsoft/vcpkg.git + cd vcpkg + ./bootstrap-vcpkg.sh + ./vcpkg integrate install + ./vcpkg install inih + +The inih port in vcpkg is kept up to date by microsoft team members and community contributors. +If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository. + +## Related links ## + +* [Conan package for inih](https://github.com/mohamedghita/conan-inih) (Conan is a C/C++ package manager) diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/cpp/INIReader.cpp b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/cpp/INIReader.cpp new file mode 100644 index 00000000..1bdac407 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/cpp/INIReader.cpp @@ -0,0 +1,116 @@ +// Read an INI file into easy-to-access name/value pairs. + +// SPDX-License-Identifier: BSD-3-Clause + +// Copyright (C) 2009-2020, Ben Hoyt + +// inih and INIReader are released under the New BSD license (see LICENSE.txt). +// Go to the project home page for more info: +// +// https://github.com/benhoyt/inih + +#include +#include +#include +#include "../ini.h" +#include "INIReader.h" + +using std::string; + +INIReader::INIReader(const string& filename) +{ + _error = ini_parse(filename.c_str(), ValueHandler, this); +} + +INIReader::INIReader(const char *buffer, size_t buffer_size) +{ + string content(buffer, buffer_size); + _error = ini_parse_string(content.c_str(), ValueHandler, this); +} + +int INIReader::ParseError() const +{ + return _error; +} + +string INIReader::Get(const string& section, const string& name, const string& default_value) const +{ + string key = MakeKey(section, name); + // Use _values.find() here instead of _values.at() to support pre C++11 compilers + return _values.count(key) ? _values.find(key)->second : default_value; +} + +string INIReader::GetString(const string& section, const string& name, const string& default_value) const +{ + const string str = Get(section, name, ""); + return str.empty() ? default_value : str; +} + +long INIReader::GetInteger(const string& section, const string& name, long default_value) const +{ + string valstr = Get(section, name, ""); + const char* value = valstr.c_str(); + char* end; + // This parses "1234" (decimal) and also "0x4D2" (hex) + long n = strtol(value, &end, 0); + return end > value ? n : default_value; +} + +double INIReader::GetReal(const string& section, const string& name, double default_value) const +{ + string valstr = Get(section, name, ""); + const char* value = valstr.c_str(); + char* end; + double n = strtod(value, &end); + return end > value ? n : default_value; +} + +bool INIReader::GetBoolean(const string& section, const string& name, bool default_value) const +{ + string valstr = Get(section, name, ""); + // Convert to lower case to make string comparisons case-insensitive + std::transform(valstr.begin(), valstr.end(), valstr.begin(), ::tolower); + if (valstr == "true" || valstr == "yes" || valstr == "on" || valstr == "1") + return true; + else if (valstr == "false" || valstr == "no" || valstr == "off" || valstr == "0") + return false; + else + return default_value; +} + +bool INIReader::HasSection(const string& section) const +{ + const string key = MakeKey(section, ""); + std::map::const_iterator pos = _values.lower_bound(key); + if (pos == _values.end()) + return false; + // Does the key at the lower_bound pos start with "section"? + return pos->first.compare(0, key.length(), key) == 0; +} + +bool INIReader::HasValue(const string& section, const string& name) const +{ + string key = MakeKey(section, name); + return _values.count(key); +} + +string INIReader::MakeKey(const string& section, const string& name) +{ + string key = section + "=" + name; + // Convert to lower case to make section/name lookups case-insensitive + std::transform(key.begin(), key.end(), key.begin(), ::tolower); + return key; +} + +int INIReader::ValueHandler(void* user, const char* section, const char* name, + const char* value) +{ + if (!name) // Happens when INI_CALL_HANDLER_ON_NEW_SECTION enabled + return 1; + INIReader* reader = static_cast(user); + string key = MakeKey(section, name); + if (reader->_values[key].size() > 0) + reader->_values[key] += "\n"; + reader->_values[key] += value ? value : ""; + return 1; +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/cpp/INIReader.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/cpp/INIReader.h new file mode 100644 index 00000000..be694a6a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/cpp/INIReader.h @@ -0,0 +1,73 @@ +// Read an INI file into easy-to-access name/value pairs. + +// SPDX-License-Identifier: BSD-3-Clause + +// Copyright (C) 2009-2020, Ben Hoyt + +// inih and INIReader are released under the New BSD license (see LICENSE.txt). +// Go to the project home page for more info: +// +// https://github.com/benhoyt/inih + +#ifndef __INIREADER_H__ +#define __INIREADER_H__ + +#include +#include + +// Read an INI file into easy-to-access name/value pairs. (Note that I've gone +// for simplicity here rather than speed, but it should be pretty decent.) +class INIReader +{ +public: + // Construct INIReader and parse given filename. See ini.h for more info + // about the parsing. + explicit INIReader(const std::string& filename); + + // Construct INIReader and parse given buffer. See ini.h for more info + // about the parsing. + explicit INIReader(const char *buffer, size_t buffer_size); + + // Return the result of ini_parse(), i.e., 0 on success, line number of + // first error on parse error, or -1 on file open error. + int ParseError() const; + + // Get a string value from INI file, returning default_value if not found. + std::string Get(const std::string& section, const std::string& name, + const std::string& default_value) const; + + // Get a string value from INI file, returning default_value if not found, + // empty, or contains only whitespace. + std::string GetString(const std::string& section, const std::string& name, + const std::string& default_value) const; + + // Get an integer (long) value from INI file, returning default_value if + // not found or not a valid integer (decimal "1234", "-1234", or hex "0x4d2"). + long GetInteger(const std::string& section, const std::string& name, long default_value) const; + + // Get a real (floating point double) value from INI file, returning + // default_value if not found or not a valid floating point value + // according to strtod(). + double GetReal(const std::string& section, const std::string& name, double default_value) const; + + // Get a boolean value from INI file, returning default_value if not found or if + // not a valid true/false value. Valid true values are "true", "yes", "on", "1", + // and valid false values are "false", "no", "off", "0" (not case sensitive). + bool GetBoolean(const std::string& section, const std::string& name, bool default_value) const; + + // Return true if the given section exists (section must contain at least + // one name=value pair). + bool HasSection(const std::string& section) const; + + // Return true if a value exists with the given section and field names. + bool HasValue(const std::string& section, const std::string& name) const; + +private: + int _error; + std::map _values; + static std::string MakeKey(const std::string& section, const std::string& name); + static int ValueHandler(void* user, const char* section, const char* name, + const char* value); +}; + +#endif // __INIREADER_H__ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/INIReaderExample.cpp b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/INIReaderExample.cpp new file mode 100644 index 00000000..985cb260 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/INIReaderExample.cpp @@ -0,0 +1,25 @@ +// Example that shows simple usage of the INIReader class + +#include +#include "../cpp/INIReader.h" + +int main() +{ + INIReader reader("../examples/test.ini"); + + if (reader.ParseError() < 0) { + std::cout << "Can't load 'test.ini'\n"; + return 1; + } + std::cout << "Config loaded from 'test.ini': version=" + << reader.GetInteger("protocol", "version", -1) << ", name=" + << reader.Get("user", "name", "UNKNOWN") << ", email=" + << reader.Get("user", "email", "UNKNOWN") << ", pi=" + << reader.GetReal("user", "pi", -1) << ", active=" + << reader.GetBoolean("user", "active", true) << "\n"; + std::cout << "Has values: user.name=" << reader.HasValue("user", "name") + << ", user.nose=" << reader.HasValue("user", "nose") << "\n"; + std::cout << "Has sections: user=" << reader.HasSection("user") + << ", fizz=" << reader.HasSection("fizz") << "\n"; + return 0; +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/config.def b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/config.def new file mode 100644 index 00000000..61132520 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/config.def @@ -0,0 +1,8 @@ +// CFG(section, name, default) + +CFG(protocol, version, "0") + +CFG(user, name, "Fatty Lumpkin") +CFG(user, email, "fatty@lumpkin.com") + +#undef CFG diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/cpptest.sh b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/cpptest.sh new file mode 100755 index 00000000..4640c244 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/cpptest.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +g++ INIReaderExample.cpp ../cpp/INIReader.cpp ../ini.c -o INIReaderExample +./INIReaderExample > cpptest.txt +rm INIReaderExample diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/cpptest.txt b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/cpptest.txt new file mode 100644 index 00000000..fac9c0de --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/cpptest.txt @@ -0,0 +1,3 @@ +Config loaded from 'test.ini': version=6, name=Bob Smith, email=bob@smith.com, pi=3.14159, active=1 +Has values: user.name=1, user.nose=0 +Has sections: user=1, fizz=0 diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/ini_dump.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/ini_dump.c new file mode 100644 index 00000000..87253ee1 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/ini_dump.c @@ -0,0 +1,40 @@ +/* ini.h example that simply dumps an INI file without comments */ + +#include +#include +#include "../ini.h" + +static int dumper(void* user, const char* section, const char* name, + const char* value) +{ + static char prev_section[50] = ""; + + if (strcmp(section, prev_section)) { + printf("%s[%s]\n", (prev_section[0] ? "\n" : ""), section); + strncpy(prev_section, section, sizeof(prev_section)); + prev_section[sizeof(prev_section) - 1] = '\0'; + } + printf("%s = %s\n", name, value); + return 1; +} + +int main(int argc, char* argv[]) +{ + int error; + + if (argc <= 1) { + printf("Usage: ini_dump filename.ini\n"); + return 1; + } + + error = ini_parse(argv[1], dumper, NULL); + if (error < 0) { + printf("Can't read '%s'!\n", argv[1]); + return 2; + } + else if (error) { + printf("Bad config file (first error on line %d)!\n", error); + return 3; + } + return 0; +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/ini_example.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/ini_example.c new file mode 100644 index 00000000..01c8eafa --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/ini_example.c @@ -0,0 +1,48 @@ +/* Example: parse a simple configuration file */ + +#include +#include +#include +#include "../ini.h" + +typedef struct +{ + int version; + const char* name; + const char* email; +} configuration; + +static int handler(void* user, const char* section, const char* name, + const char* value) +{ + configuration* pconfig = (configuration*)user; + + #define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0 + if (MATCH("protocol", "version")) { + pconfig->version = atoi(value); + } else if (MATCH("user", "name")) { + pconfig->name = strdup(value); + } else if (MATCH("user", "email")) { + pconfig->email = strdup(value); + } else { + return 0; /* unknown section/name, error */ + } + return 1; +} + +int main(int argc, char* argv[]) +{ + configuration config; + + if (ini_parse("test.ini", handler, &config) < 0) { + printf("Can't load 'test.ini'\n"); + return 1; + } + printf("Config loaded from 'test.ini': version=%d, name=%s, email=%s\n", + config.version, config.name, config.email); + + free((void*)config.name); + free((void*)config.email); + + return 0; +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/ini_xmacros.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/ini_xmacros.c new file mode 100644 index 00000000..a2cab43b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/ini_xmacros.c @@ -0,0 +1,46 @@ +/* Parse a configuration file into a struct using X-Macros */ + +#include +#include +#include "../ini.h" + +/* define the config struct type */ +typedef struct { + #define CFG(s, n, default) char *s##_##n; + #include "config.def" +} config; + +/* create one and fill in its default values */ +config Config = { + #define CFG(s, n, default) default, + #include "config.def" +}; + +/* process a line of the INI file, storing valid values into config struct */ +int handler(void *user, const char *section, const char *name, + const char *value) +{ + config *cfg = (config *)user; + + if (0) ; + #define CFG(s, n, default) else if (strcmp(section, #s)==0 && \ + strcmp(name, #n)==0) cfg->s##_##n = strdup(value); + #include "config.def" + + return 1; +} + +/* print all the variables in the config, one per line */ +void dump_config(config *cfg) +{ + #define CFG(s, n, default) printf("%s_%s = %s\n", #s, #n, cfg->s##_##n); + #include "config.def" +} + +int main(int argc, char* argv[]) +{ + if (ini_parse("test.ini", handler, &Config) < 0) + printf("Can't load 'test.ini', using defaults\n"); + dump_config(&Config); + return 0; +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/test.ini b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/test.ini new file mode 100644 index 00000000..680c3b9a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/examples/test.ini @@ -0,0 +1,10 @@ +; Test config file for ini_example.c and INIReaderTest.cpp + +[protocol] ; Protocol configuration +version=6 ; IPv6 + +[user] +name = Bob Smith ; Spaces around '=' are stripped +email = bob@smith.com ; And comments (like this) ignored +active = true ; Test a boolean +pi = 3.14159 ; Test a floating point number diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/ini.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/ini.c new file mode 100644 index 00000000..d19d6135 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/ini.c @@ -0,0 +1,284 @@ +/* inih -- simple .INI file parser + +SPDX-License-Identifier: BSD-3-Clause + +Copyright (C) 2009-2020, Ben Hoyt + +inih is released under the New BSD license (see LICENSE.txt). Go to the project +home page for more info: + +https://github.com/benhoyt/inih + +*/ + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include +#include +#include + +#include "ini.h" + +#if !INI_USE_STACK +#include +#endif + +#define MAX_SECTION 50 +#define MAX_NAME 50 + +/* Used by ini_parse_string() to keep track of string parsing state. */ +typedef struct { + const char* ptr; + size_t num_left; +} ini_parse_string_ctx; + +/* Strip whitespace chars off end of given string, in place. Return s. */ +static char* rstrip(char* s) +{ + char* p = s + strlen(s); + while (p > s && isspace((unsigned char)(*--p))) + *p = '\0'; + return s; +} + +/* Return pointer to first non-whitespace char in given string. */ +static char* lskip(const char* s) +{ + while (*s && isspace((unsigned char)(*s))) + s++; + return (char*)s; +} + +/* Return pointer to first char (of chars) or inline comment in given string, + or pointer to null at end of string if neither found. Inline comment must + be prefixed by a whitespace character to register as a comment. */ +static char* find_chars_or_comment(const char* s, const char* chars) +{ +#if INI_ALLOW_INLINE_COMMENTS + int was_space = 0; + while (*s && (!chars || !strchr(chars, *s)) && + !(was_space && strchr(INI_INLINE_COMMENT_PREFIXES, *s))) { + was_space = isspace((unsigned char)(*s)); + s++; + } +#else + while (*s && (!chars || !strchr(chars, *s))) { + s++; + } +#endif + return (char*)s; +} + +/* Version of strncpy that ensures dest (size bytes) is null-terminated. */ +static char* strncpy0(char* dest, const char* src, size_t size) +{ + strncpy(dest, src, size - 1); + dest[size - 1] = '\0'; + return dest; +} + +/* See documentation in header file. */ +int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, + void* user) +{ + /* Uses a fair bit of stack (use heap instead if you need to) */ +#if INI_USE_STACK + char line[INI_MAX_LINE]; + int max_line = INI_MAX_LINE; +#else + char* line; + size_t max_line = INI_INITIAL_ALLOC; +#endif +#if INI_ALLOW_REALLOC && !INI_USE_STACK + char* new_line; + size_t offset; +#endif + char section[MAX_SECTION] = ""; + char prev_name[MAX_NAME] = ""; + + char* start; + char* end; + char* name; + char* value; + int lineno = 0; + int error = 0; + +#if !INI_USE_STACK + line = (char*)malloc(INI_INITIAL_ALLOC); + if (!line) { + return -2; + } +#endif + +#if INI_HANDLER_LINENO +#define HANDLER(u, s, n, v) handler(u, s, n, v, lineno) +#else +#define HANDLER(u, s, n, v) handler(u, s, n, v) +#endif + + /* Scan through stream line by line */ + while (reader(line, (int)max_line, stream) != NULL) { +#if INI_ALLOW_REALLOC && !INI_USE_STACK + offset = strlen(line); + while (offset == max_line - 1 && line[offset - 1] != '\n') { + max_line *= 2; + if (max_line > INI_MAX_LINE) + max_line = INI_MAX_LINE; + new_line = realloc(line, max_line); + if (!new_line) { + free(line); + return -2; + } + line = new_line; + if (reader(line + offset, (int)(max_line - offset), stream) == NULL) + break; + if (max_line >= INI_MAX_LINE) + break; + offset += strlen(line + offset); + } +#endif + + lineno++; + + start = line; +#if INI_ALLOW_BOM + if (lineno == 1 && (unsigned char)start[0] == 0xEF && + (unsigned char)start[1] == 0xBB && + (unsigned char)start[2] == 0xBF) { + start += 3; + } +#endif + start = lskip(rstrip(start)); + + if (strchr(INI_START_COMMENT_PREFIXES, *start)) { + /* Start-of-line comment */ + } +#if INI_ALLOW_MULTILINE + else if (*prev_name && *start && start > line) { + /* Non-blank line with leading whitespace, treat as continuation + of previous name's value (as per Python configparser). */ + if (!HANDLER(user, section, prev_name, start) && !error) + error = lineno; + } +#endif + else if (*start == '[') { + /* A "[section]" line */ + end = find_chars_or_comment(start + 1, "]"); + if (*end == ']') { + *end = '\0'; + strncpy0(section, start + 1, sizeof(section)); + *prev_name = '\0'; +#if INI_CALL_HANDLER_ON_NEW_SECTION + if (!HANDLER(user, section, NULL, NULL) && !error) + error = lineno; +#endif + } + else if (!error) { + /* No ']' found on section line */ + error = lineno; + } + } + else if (*start) { + /* Not a comment, must be a name[=:]value pair */ + end = find_chars_or_comment(start, "=:"); + if (*end == '=' || *end == ':') { + *end = '\0'; + name = rstrip(start); + value = end + 1; +#if INI_ALLOW_INLINE_COMMENTS + end = find_chars_or_comment(value, NULL); + if (*end) + *end = '\0'; +#endif + value = lskip(value); + rstrip(value); + + /* Valid name[=:]value pair found, call handler */ + strncpy0(prev_name, name, sizeof(prev_name)); + if (!HANDLER(user, section, name, value) && !error) + error = lineno; + } + else if (!error) { + /* No '=' or ':' found on name[=:]value line */ +#if INI_ALLOW_NO_VALUE + *end = '\0'; + name = rstrip(start); + if (!HANDLER(user, section, name, NULL) && !error) + error = lineno; +#else + error = lineno; +#endif + } + } + +#if INI_STOP_ON_FIRST_ERROR + if (error) + break; +#endif + } + +#if !INI_USE_STACK + free(line); +#endif + + return error; +} + +/* See documentation in header file. */ +int ini_parse_file(FILE* file, ini_handler handler, void* user) +{ + return ini_parse_stream((ini_reader)fgets, file, handler, user); +} + +/* See documentation in header file. */ +int ini_parse(const char* filename, ini_handler handler, void* user) +{ + FILE* file; + int error; + + file = fopen(filename, "r"); + if (!file) + return -1; + error = ini_parse_file(file, handler, user); + fclose(file); + return error; +} + +/* An ini_reader function to read the next line from a string buffer. This + is the fgets() equivalent used by ini_parse_string(). */ +static char* ini_reader_string(char* str, int num, void* stream) { + ini_parse_string_ctx* ctx = (ini_parse_string_ctx*)stream; + const char* ctx_ptr = ctx->ptr; + size_t ctx_num_left = ctx->num_left; + char* strp = str; + char c; + + if (ctx_num_left == 0 || num < 2) + return NULL; + + while (num > 1 && ctx_num_left != 0) { + c = *ctx_ptr++; + ctx_num_left--; + *strp++ = c; + if (c == '\n') + break; + num--; + } + + *strp = '\0'; + ctx->ptr = ctx_ptr; + ctx->num_left = ctx_num_left; + return str; +} + +/* See documentation in header file. */ +int ini_parse_string(const char* string, ini_handler handler, void* user) { + ini_parse_string_ctx ctx; + + ctx.ptr = string; + ctx.num_left = strlen(string); + return ini_parse_stream((ini_reader)ini_reader_string, &ctx, handler, + user); +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/ini.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/ini.h new file mode 100644 index 00000000..441f560b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/ini.h @@ -0,0 +1,148 @@ +/* inih -- simple .INI file parser + +SPDX-License-Identifier: BSD-3-Clause + +Copyright (C) 2009-2020, Ben Hoyt + +inih is released under the New BSD license (see LICENSE.txt). Go to the project +home page for more info: + +https://github.com/benhoyt/inih + +*/ + +#ifndef __INI_H__ +#define __INI_H__ + +/* Make this header file easier to include in C++ code */ +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Nonzero if ini_handler callback should accept lineno parameter. */ +#ifndef INI_HANDLER_LINENO +#define INI_HANDLER_LINENO 0 +#endif + +/* Typedef for prototype of handler function. */ +#if INI_HANDLER_LINENO +typedef int (*ini_handler)(void* user, const char* section, + const char* name, const char* value, + int lineno); +#else +typedef int (*ini_handler)(void* user, const char* section, + const char* name, const char* value); +#endif + +/* Typedef for prototype of fgets-style reader function. */ +typedef char* (*ini_reader)(char* str, int num, void* stream); + +/* Parse given INI-style file. May have [section]s, name=value pairs + (whitespace stripped), and comments starting with ';' (semicolon). Section + is "" if name=value pair parsed before any section heading. name:value + pairs are also supported as a concession to Python's configparser. + + For each name=value pair parsed, call handler function with given user + pointer as well as section, name, and value (data only valid for duration + of handler call). Handler should return nonzero on success, zero on error. + + Returns 0 on success, line number of first error on parse error (doesn't + stop on first error), -1 on file open error, or -2 on memory allocation + error (only when INI_USE_STACK is zero). +*/ +int ini_parse(const char* filename, ini_handler handler, void* user); + +/* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't + close the file when it's finished -- the caller must do that. */ +int ini_parse_file(FILE* file, ini_handler handler, void* user); + +/* Same as ini_parse(), but takes an ini_reader function pointer instead of + filename. Used for implementing custom or string-based I/O (see also + ini_parse_string). */ +int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler, + void* user); + +/* Same as ini_parse(), but takes a zero-terminated string with the INI data +instead of a file. Useful for parsing INI data from a network socket or +already in memory. */ +int ini_parse_string(const char* string, ini_handler handler, void* user); + +/* Nonzero to allow multi-line value parsing, in the style of Python's + configparser. If allowed, ini_parse() will call the handler with the same + name for each subsequent line parsed. */ +#ifndef INI_ALLOW_MULTILINE +#define INI_ALLOW_MULTILINE 1 +#endif + +/* Nonzero to allow a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of + the file. See https://github.com/benhoyt/inih/issues/21 */ +#ifndef INI_ALLOW_BOM +#define INI_ALLOW_BOM 1 +#endif + +/* Chars that begin a start-of-line comment. Per Python configparser, allow + both ; and # comments at the start of a line by default. */ +#ifndef INI_START_COMMENT_PREFIXES +#define INI_START_COMMENT_PREFIXES ";#" +#endif + +/* Nonzero to allow inline comments (with valid inline comment characters + specified by INI_INLINE_COMMENT_PREFIXES). Set to 0 to turn off and match + Python 3.2+ configparser behaviour. */ +#ifndef INI_ALLOW_INLINE_COMMENTS +#define INI_ALLOW_INLINE_COMMENTS 1 +#endif +#ifndef INI_INLINE_COMMENT_PREFIXES +#define INI_INLINE_COMMENT_PREFIXES ";" +#endif + +/* Nonzero to use stack for line buffer, zero to use heap (malloc/free). */ +#ifndef INI_USE_STACK +#define INI_USE_STACK 1 +#endif + +/* Maximum line length for any line in INI file (stack or heap). Note that + this must be 3 more than the longest line (due to '\r', '\n', and '\0'). */ +#ifndef INI_MAX_LINE +#define INI_MAX_LINE 200 +#endif + +/* Nonzero to allow heap line buffer to grow via realloc(), zero for a + fixed-size buffer of INI_MAX_LINE bytes. Only applies if INI_USE_STACK is + zero. */ +#ifndef INI_ALLOW_REALLOC +#define INI_ALLOW_REALLOC 0 +#endif + +/* Initial size in bytes for heap line buffer. Only applies if INI_USE_STACK + is zero. */ +#ifndef INI_INITIAL_ALLOC +#define INI_INITIAL_ALLOC 200 +#endif + +/* Stop parsing on first error (default is to keep parsing). */ +#ifndef INI_STOP_ON_FIRST_ERROR +#define INI_STOP_ON_FIRST_ERROR 0 +#endif + +/* Nonzero to call the handler at the start of each new section (with + name and value NULL). Default is to only call the handler on + each name=value pair. */ +#ifndef INI_CALL_HANDLER_ON_NEW_SECTION +#define INI_CALL_HANDLER_ON_NEW_SECTION 0 +#endif + +/* Nonzero to allow a name without a value (no '=' or ':' on the line) and + call the handler with value NULL in this case. Default is to treat + no-value lines as an error. */ +#ifndef INI_ALLOW_NO_VALUE +#define INI_ALLOW_NO_VALUE 0 +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __INI_H__ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/meson.build b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/meson.build new file mode 100644 index 00000000..f2612703 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/meson.build @@ -0,0 +1,58 @@ +project('inih', + ['c','cpp'], + meson_version : '>= 0.46.0', + default_options : ['default_library=both'], + license : 'BSD-3-Clause', + version : '48' +) + +pkg = import('pkgconfig') + +#### inih #### +install_headers('ini.h') + +inc_inih = include_directories('.') + +lib_inih = library('inih', + ['ini.c'], + include_directories : inc_inih, + install : true, + version : meson.project_version(), + soversion : '0' +) + +pkg.generate(lib_inih, + name : 'inih', + description : 'simple .INI file parser', + version : meson.project_version() +) + +inih_dep = declare_dependency( + link_with : lib_inih, + include_directories : inc_inih +) + +#### INIReader #### +install_headers('cpp/INIReader.h') + +inc_INIReader = include_directories('cpp') + +lib_INIReader = library('INIReader', + ['cpp/INIReader.cpp'], + include_directories : inc_INIReader, + dependencies : inih_dep, + install : true, + version : meson.project_version(), + soversion : '0' +) + +pkg.generate(lib_INIReader, + name : 'INIReader', + description : 'simple .INI file parser for C++', + version : meson.project_version() +) + +INIReader_dep = declare_dependency( + link_with : lib_inih, + include_directories : inc_INIReader +) diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/bad_comment.ini b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/bad_comment.ini new file mode 100644 index 00000000..d4bab4ae --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/bad_comment.ini @@ -0,0 +1 @@ +This is an error diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/bad_multi.ini b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/bad_multi.ini new file mode 100644 index 00000000..3ec342f2 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/bad_multi.ini @@ -0,0 +1 @@ + indented diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/bad_section.ini b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/bad_section.ini new file mode 100644 index 00000000..689a4e5c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/bad_section.ini @@ -0,0 +1,5 @@ +[section1] +name1=value1 +[section2 +[section3 ; comment ] +name2=value2 diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_allow_no_value.txt b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_allow_no_value.txt new file mode 100644 index 00000000..1486c88f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_allow_no_value.txt @@ -0,0 +1,69 @@ +no_file.ini: e=-1 user=0 +... [section1] +... one=This is a test; +... two=1234; +... [ section 2 ] +... happy=4; +... sad=; +... [comment_test] +... test1=1;2;3; +... test2=2;3;4;this won't be a comment, needs whitespace before ';'; +... test;3=345; +... test4=4#5#6; +... test7=; +... test8=; not a comment, needs whitespace before ';'; +... [colon_tests] +... Content-Type=text/html; +... foo=bar; +... adams=42; +... funny1=with = equals; +... funny2=with : colons; +... funny3=two = equals; +... funny4=two : colons; +normal.ini: e=0 user=101 +... [section1] +... name1=value1; +... name2=value2; +bad_section.ini: e=3 user=102 +... This is an error; +bad_comment.ini: e=0 user=103 +... [section] +... a=b; +... user=parse_error; +... c=d; +user_error.ini: e=3 user=104 +... [section1] +... single1=abc; +... multi=this is a; +... multi=multi-line value; +... single2=xyz; +... [section2] +... multi=a; +... multi=b; +... multi=c; +... [section3] +... single=ghi; +... multi=the quick; +... multi=brown fox; +... name=bob smith; +multi_line.ini: e=0 user=105 +... indented; +bad_multi.ini: e=0 user=106 +... [bom_section] +... bom_name=bom_value; +... key“=value“; +bom.ini: e=0 user=107 +... [section1] +... single1=abc; +... single2=xyz; +... single1=def; +... single2=qrs; +duplicate_sections.ini: e=0 user=108 +... [section_list] +... section0; +... section1; +... [section0] +... key0=val0; +... [section1] +... key1=val1; +no_value.ini: e=0 user=109 diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_call_handler_on_new_section.txt b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_call_handler_on_new_section.txt new file mode 100644 index 00000000..d1eec9d9 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_call_handler_on_new_section.txt @@ -0,0 +1,67 @@ +no_file.ini: e=-1 user=0 +... [section1] +... one=This is a test; +... two=1234; +... [ section 2 ] +... happy=4; +... sad=; +... [empty] +... [comment_test] +... test1=1;2;3; +... test2=2;3;4;this won't be a comment, needs whitespace before ';'; +... test;3=345; +... test4=4#5#6; +... test7=; +... test8=; not a comment, needs whitespace before ';'; +... [colon_tests] +... Content-Type=text/html; +... foo=bar; +... adams=42; +... funny1=with = equals; +... funny2=with : colons; +... funny3=two = equals; +... funny4=two : colons; +normal.ini: e=0 user=101 +... [section1] +... name1=value1; +... name2=value2; +bad_section.ini: e=3 user=102 +bad_comment.ini: e=1 user=102 +... [section] +... a=b; +... user=parse_error; +... c=d; +user_error.ini: e=3 user=104 +... [section1] +... single1=abc; +... multi=this is a; +... multi=multi-line value; +... single2=xyz; +... [section2] +... multi=a; +... multi=b; +... multi=c; +... [section3] +... single=ghi; +... multi=the quick; +... multi=brown fox; +... name=bob smith; +multi_line.ini: e=0 user=105 +bad_multi.ini: e=1 user=105 +... [bom_section] +... bom_name=bom_value; +... key“=value“; +bom.ini: e=0 user=107 +... [section1] +... single1=abc; +... single2=xyz; +... [section1] +... single1=def; +... single2=qrs; +duplicate_sections.ini: e=0 user=108 +... [section_list] +... [section0] +... key0=val0; +... [section1] +... key1=val1; +no_value.ini: e=2 user=109 diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_disallow_inline_comments.txt b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_disallow_inline_comments.txt new file mode 100644 index 00000000..327a495f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_disallow_inline_comments.txt @@ -0,0 +1,65 @@ +no_file.ini: e=-1 user=0 +... [section1] +... one=This is a test ; name=value comment; +... two=1234; +... [ section 2 ] +... happy=4; +... sad=; +... [comment_test] +... test1=1;2;3 ; only this will be a comment; +... test2=2;3;4;this won't be a comment, needs whitespace before ';'; +... test;3=345 ; key should be "test;3"; +... test4=4#5#6 ; '#' only starts a comment at start of line; +... test7=; blank value, except if inline comments disabled; +... test8=; not a comment, needs whitespace before ';'; +... [colon_tests] +... Content-Type=text/html; +... foo=bar; +... adams=42; +... funny1=with = equals; +... funny2=with : colons; +... funny3=two = equals; +... funny4=two : colons; +normal.ini: e=0 user=101 +... [section1] +... name1=value1; +... [section3 ; comment ] +... name2=value2; +bad_section.ini: e=3 user=102 +bad_comment.ini: e=1 user=102 +... [section] +... a=b; +... user=parse_error; +... c=d; +user_error.ini: e=3 user=104 +... [section1] +... single1=abc; +... multi=this is a; +... multi=multi-line value; +... single2=xyz; +... [section2] +... multi=a; +... multi=b; +... multi=c; +... [section3] +... single=ghi; +... multi=the quick; +... multi=brown fox; +... name=bob smith ; comment line 1; +multi_line.ini: e=0 user=105 +bad_multi.ini: e=1 user=105 +... [bom_section] +... bom_name=bom_value; +... key“=value“; +bom.ini: e=0 user=107 +... [section1] +... single1=abc; +... single2=xyz; +... single1=def; +... single2=qrs; +duplicate_sections.ini: e=0 user=108 +... [section0] +... key0=val0; +... [section1] +... key1=val1; +no_value.ini: e=2 user=109 diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_handler_lineno.txt b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_handler_lineno.txt new file mode 100644 index 00000000..b05fb6c2 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_handler_lineno.txt @@ -0,0 +1,64 @@ +no_file.ini: e=-1 user=0 +... [section1] +... one=This is a test; line 3 +... two=1234; line 4 +... [ section 2 ] +... happy=4; line 8 +... sad=; line 9 +... [comment_test] +... test1=1;2;3; line 15 +... test2=2;3;4;this won't be a comment, needs whitespace before ';'; line 16 +... test;3=345; line 17 +... test4=4#5#6; line 18 +... test7=; line 21 +... test8=; not a comment, needs whitespace before ';'; line 22 +... [colon_tests] +... Content-Type=text/html; line 25 +... foo=bar; line 26 +... adams=42; line 27 +... funny1=with = equals; line 28 +... funny2=with : colons; line 29 +... funny3=two = equals; line 30 +... funny4=two : colons; line 31 +normal.ini: e=0 user=101 +... [section1] +... name1=value1; line 2 +... name2=value2; line 5 +bad_section.ini: e=3 user=102 +bad_comment.ini: e=1 user=102 +... [section] +... a=b; line 2 +... user=parse_error; line 3 +... c=d; line 4 +user_error.ini: e=3 user=104 +... [section1] +... single1=abc; line 2 +... multi=this is a; line 3 +... multi=multi-line value; line 4 +... single2=xyz; line 5 +... [section2] +... multi=a; line 7 +... multi=b; line 8 +... multi=c; line 9 +... [section3] +... single=ghi; line 11 +... multi=the quick; line 12 +... multi=brown fox; line 13 +... name=bob smith; line 14 +multi_line.ini: e=0 user=105 +bad_multi.ini: e=1 user=105 +... [bom_section] +... bom_name=bom_value; line 2 +... key“=value“; line 3 +bom.ini: e=0 user=107 +... [section1] +... single1=abc; line 2 +... single2=xyz; line 3 +... single1=def; line 5 +... single2=qrs; line 6 +duplicate_sections.ini: e=0 user=108 +... [section0] +... key0=val0; line 6 +... [section1] +... key1=val1; line 9 +no_value.ini: e=2 user=109 diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_heap.txt b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_heap.txt new file mode 100644 index 00000000..40b39b2c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_heap.txt @@ -0,0 +1,64 @@ +no_file.ini: e=-1 user=0 +... [section1] +... one=This is a test; +... two=1234; +... [ section 2 ] +... happy=4; +... sad=; +... [comment_test] +... test1=1;2;3; +... test2=2;3;4;this won't be a comment, needs whitespace before ';'; +... test;3=345; +... test4=4#5#6; +... test7=; +... test8=; not a comment, needs whitespace before ';'; +... [colon_tests] +... Content-Type=text/html; +... foo=bar; +... adams=42; +... funny1=with = equals; +... funny2=with : colons; +... funny3=two = equals; +... funny4=two : colons; +normal.ini: e=0 user=101 +... [section1] +... name1=value1; +... name2=value2; +bad_section.ini: e=3 user=102 +bad_comment.ini: e=1 user=102 +... [section] +... a=b; +... user=parse_error; +... c=d; +user_error.ini: e=3 user=104 +... [section1] +... single1=abc; +... multi=this is a; +... multi=multi-line value; +... single2=xyz; +... [section2] +... multi=a; +... multi=b; +... multi=c; +... [section3] +... single=ghi; +... multi=the quick; +... multi=brown fox; +... name=bob smith; +multi_line.ini: e=0 user=105 +bad_multi.ini: e=1 user=105 +... [bom_section] +... bom_name=bom_value; +... key“=value“; +bom.ini: e=0 user=107 +... [section1] +... single1=abc; +... single2=xyz; +... single1=def; +... single2=qrs; +duplicate_sections.ini: e=0 user=108 +... [section0] +... key0=val0; +... [section1] +... key1=val1; +no_value.ini: e=2 user=109 diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_heap_max_line.txt b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_heap_max_line.txt new file mode 100644 index 00000000..a9c2e8e6 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_heap_max_line.txt @@ -0,0 +1,68 @@ +no_file.ini: e=-1 user=0 +... [section1] +... one=This is a test; +... two=1234; +... [ section 2 ] +... happy=4; +... sad=; +... [comment_test] +... test1=1;2;3; +... test2=2;3;4;this; +... test2=needs whitespace b; +... test;3=345; +... test4=4#5#6; +... test4=only starts a comm; +... test7=; +... test8=; not a comm; +... [colon_tests] +... Content-Type=text/; +... foo=bar; +... adams=42; +... funny1=with = equ; +... funny2=with : col; +... funny3=two = equa; +... funny4=two : colo; +normal.ini: e=2 user=101 +... [section1] +... name1=value1; +... name2=value2; +bad_section.ini: e=3 user=102 +bad_comment.ini: e=1 user=102 +... [section] +... a=b; +... user=parse_error; +... c=d; +user_error.ini: e=3 user=104 +... [section1] +... single1=abc; +... multi=this is a; +... multi=multi-line; +... single2=xyz; +... [section2] +... multi=a; +... multi=b; +... multi=c; +... [section3] +... single=ghi; +... multi=the quick; +... multi=brown fox; +... name=bob smith; +... name=comment line 1; +... name=comment line 2; +multi_line.ini: e=5 user=105 +bad_multi.ini: e=1 user=105 +... [bom_section] +... bom_name=bom_value; +... key“=value“; +bom.ini: e=0 user=107 +... [section1] +... single1=abc; +... single2=xyz; +... single1=def; +... single2=qrs; +duplicate_sections.ini: e=0 user=108 +... [section0] +... key0=val0; +... [section1] +... key1=val1; +no_value.ini: e=2 user=109 diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_heap_realloc.txt b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_heap_realloc.txt new file mode 100644 index 00000000..40b39b2c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_heap_realloc.txt @@ -0,0 +1,64 @@ +no_file.ini: e=-1 user=0 +... [section1] +... one=This is a test; +... two=1234; +... [ section 2 ] +... happy=4; +... sad=; +... [comment_test] +... test1=1;2;3; +... test2=2;3;4;this won't be a comment, needs whitespace before ';'; +... test;3=345; +... test4=4#5#6; +... test7=; +... test8=; not a comment, needs whitespace before ';'; +... [colon_tests] +... Content-Type=text/html; +... foo=bar; +... adams=42; +... funny1=with = equals; +... funny2=with : colons; +... funny3=two = equals; +... funny4=two : colons; +normal.ini: e=0 user=101 +... [section1] +... name1=value1; +... name2=value2; +bad_section.ini: e=3 user=102 +bad_comment.ini: e=1 user=102 +... [section] +... a=b; +... user=parse_error; +... c=d; +user_error.ini: e=3 user=104 +... [section1] +... single1=abc; +... multi=this is a; +... multi=multi-line value; +... single2=xyz; +... [section2] +... multi=a; +... multi=b; +... multi=c; +... [section3] +... single=ghi; +... multi=the quick; +... multi=brown fox; +... name=bob smith; +multi_line.ini: e=0 user=105 +bad_multi.ini: e=1 user=105 +... [bom_section] +... bom_name=bom_value; +... key“=value“; +bom.ini: e=0 user=107 +... [section1] +... single1=abc; +... single2=xyz; +... single1=def; +... single2=qrs; +duplicate_sections.ini: e=0 user=108 +... [section0] +... key0=val0; +... [section1] +... key1=val1; +no_value.ini: e=2 user=109 diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_heap_realloc_max_line.txt b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_heap_realloc_max_line.txt new file mode 100644 index 00000000..a9c2e8e6 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_heap_realloc_max_line.txt @@ -0,0 +1,68 @@ +no_file.ini: e=-1 user=0 +... [section1] +... one=This is a test; +... two=1234; +... [ section 2 ] +... happy=4; +... sad=; +... [comment_test] +... test1=1;2;3; +... test2=2;3;4;this; +... test2=needs whitespace b; +... test;3=345; +... test4=4#5#6; +... test4=only starts a comm; +... test7=; +... test8=; not a comm; +... [colon_tests] +... Content-Type=text/; +... foo=bar; +... adams=42; +... funny1=with = equ; +... funny2=with : col; +... funny3=two = equa; +... funny4=two : colo; +normal.ini: e=2 user=101 +... [section1] +... name1=value1; +... name2=value2; +bad_section.ini: e=3 user=102 +bad_comment.ini: e=1 user=102 +... [section] +... a=b; +... user=parse_error; +... c=d; +user_error.ini: e=3 user=104 +... [section1] +... single1=abc; +... multi=this is a; +... multi=multi-line; +... single2=xyz; +... [section2] +... multi=a; +... multi=b; +... multi=c; +... [section3] +... single=ghi; +... multi=the quick; +... multi=brown fox; +... name=bob smith; +... name=comment line 1; +... name=comment line 2; +multi_line.ini: e=5 user=105 +bad_multi.ini: e=1 user=105 +... [bom_section] +... bom_name=bom_value; +... key“=value“; +bom.ini: e=0 user=107 +... [section1] +... single1=abc; +... single2=xyz; +... single1=def; +... single2=qrs; +duplicate_sections.ini: e=0 user=108 +... [section0] +... key0=val0; +... [section1] +... key1=val1; +no_value.ini: e=2 user=109 diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_heap_string.txt b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_heap_string.txt new file mode 100644 index 00000000..4d3627f6 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_heap_string.txt @@ -0,0 +1,21 @@ +empty string: e=0 user=0 +... [section] +... foo=bar; +... bazz=buzz quxx; +basic: e=0 user=101 +... [section] +... hello=world; +... forty_two=42; +crlf: e=0 user=102 +... [sec] +... foo=0123456789012; +... bar=4321; +long line: e=3 user=103 +... [sec] +... foo=0123456789012; +... bix=1234; +long continued: e=0 user=104 +... [s] +... a=1; +... c=3; +error: e=3 user=105 diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_multi.txt b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_multi.txt new file mode 100644 index 00000000..40b39b2c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_multi.txt @@ -0,0 +1,64 @@ +no_file.ini: e=-1 user=0 +... [section1] +... one=This is a test; +... two=1234; +... [ section 2 ] +... happy=4; +... sad=; +... [comment_test] +... test1=1;2;3; +... test2=2;3;4;this won't be a comment, needs whitespace before ';'; +... test;3=345; +... test4=4#5#6; +... test7=; +... test8=; not a comment, needs whitespace before ';'; +... [colon_tests] +... Content-Type=text/html; +... foo=bar; +... adams=42; +... funny1=with = equals; +... funny2=with : colons; +... funny3=two = equals; +... funny4=two : colons; +normal.ini: e=0 user=101 +... [section1] +... name1=value1; +... name2=value2; +bad_section.ini: e=3 user=102 +bad_comment.ini: e=1 user=102 +... [section] +... a=b; +... user=parse_error; +... c=d; +user_error.ini: e=3 user=104 +... [section1] +... single1=abc; +... multi=this is a; +... multi=multi-line value; +... single2=xyz; +... [section2] +... multi=a; +... multi=b; +... multi=c; +... [section3] +... single=ghi; +... multi=the quick; +... multi=brown fox; +... name=bob smith; +multi_line.ini: e=0 user=105 +bad_multi.ini: e=1 user=105 +... [bom_section] +... bom_name=bom_value; +... key“=value“; +bom.ini: e=0 user=107 +... [section1] +... single1=abc; +... single2=xyz; +... single1=def; +... single2=qrs; +duplicate_sections.ini: e=0 user=108 +... [section0] +... key0=val0; +... [section1] +... key1=val1; +no_value.ini: e=2 user=109 diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_multi_max_line.txt b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_multi_max_line.txt new file mode 100644 index 00000000..a9c2e8e6 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_multi_max_line.txt @@ -0,0 +1,68 @@ +no_file.ini: e=-1 user=0 +... [section1] +... one=This is a test; +... two=1234; +... [ section 2 ] +... happy=4; +... sad=; +... [comment_test] +... test1=1;2;3; +... test2=2;3;4;this; +... test2=needs whitespace b; +... test;3=345; +... test4=4#5#6; +... test4=only starts a comm; +... test7=; +... test8=; not a comm; +... [colon_tests] +... Content-Type=text/; +... foo=bar; +... adams=42; +... funny1=with = equ; +... funny2=with : col; +... funny3=two = equa; +... funny4=two : colo; +normal.ini: e=2 user=101 +... [section1] +... name1=value1; +... name2=value2; +bad_section.ini: e=3 user=102 +bad_comment.ini: e=1 user=102 +... [section] +... a=b; +... user=parse_error; +... c=d; +user_error.ini: e=3 user=104 +... [section1] +... single1=abc; +... multi=this is a; +... multi=multi-line; +... single2=xyz; +... [section2] +... multi=a; +... multi=b; +... multi=c; +... [section3] +... single=ghi; +... multi=the quick; +... multi=brown fox; +... name=bob smith; +... name=comment line 1; +... name=comment line 2; +multi_line.ini: e=5 user=105 +bad_multi.ini: e=1 user=105 +... [bom_section] +... bom_name=bom_value; +... key“=value“; +bom.ini: e=0 user=107 +... [section1] +... single1=abc; +... single2=xyz; +... single1=def; +... single2=qrs; +duplicate_sections.ini: e=0 user=108 +... [section0] +... key0=val0; +... [section1] +... key1=val1; +no_value.ini: e=2 user=109 diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_single.txt b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_single.txt new file mode 100644 index 00000000..bff89bb1 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_single.txt @@ -0,0 +1,60 @@ +no_file.ini: e=-1 user=0 +... [section1] +... one=This is a test; +... two=1234; +... [ section 2 ] +... happy=4; +... sad=; +... [comment_test] +... test1=1;2;3; +... test2=2;3;4;this won't be a comment, needs whitespace before ';'; +... test;3=345; +... test4=4#5#6; +... test7=; +... test8=; not a comment, needs whitespace before ';'; +... [colon_tests] +... Content-Type=text/html; +... foo=bar; +... adams=42; +... funny1=with = equals; +... funny2=with : colons; +... funny3=two = equals; +... funny4=two : colons; +normal.ini: e=0 user=101 +... [section1] +... name1=value1; +... name2=value2; +bad_section.ini: e=3 user=102 +bad_comment.ini: e=1 user=102 +... [section] +... a=b; +... user=parse_error; +... c=d; +user_error.ini: e=3 user=104 +... [section1] +... single1=abc; +... multi=this is a; +... single2=xyz; +... [section2] +... multi=a; +... [section3] +... single=ghi; +... multi=the quick; +... name=bob smith; +multi_line.ini: e=4 user=105 +bad_multi.ini: e=1 user=105 +... [bom_section] +... bom_name=bom_value; +... key“=value“; +bom.ini: e=0 user=107 +... [section1] +... single1=abc; +... single2=xyz; +... single1=def; +... single2=qrs; +duplicate_sections.ini: e=0 user=108 +... [section0] +... key0=val0; +... [section1] +... key1=val1; +no_value.ini: e=2 user=109 diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_stop_on_first_error.txt b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_stop_on_first_error.txt new file mode 100644 index 00000000..6663e1ff --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_stop_on_first_error.txt @@ -0,0 +1,58 @@ +no_file.ini: e=-1 user=0 +... [section1] +... one=This is a test; +... two=1234; +... [ section 2 ] +... happy=4; +... sad=; +... [comment_test] +... test1=1;2;3; +... test2=2;3;4;this won't be a comment, needs whitespace before ';'; +... test;3=345; +... test4=4#5#6; +... test7=; +... test8=; not a comment, needs whitespace before ';'; +... [colon_tests] +... Content-Type=text/html; +... foo=bar; +... adams=42; +... funny1=with = equals; +... funny2=with : colons; +... funny3=two = equals; +... funny4=two : colons; +normal.ini: e=0 user=101 +... [section1] +... name1=value1; +bad_section.ini: e=3 user=102 +bad_comment.ini: e=1 user=102 +... [section] +... a=b; +... user=parse_error; +user_error.ini: e=3 user=104 +... [section1] +... single1=abc; +... multi=this is a; +... multi=multi-line value; +... single2=xyz; +... [section2] +... multi=a; +... multi=b; +... multi=c; +... [section3] +... single=ghi; +... multi=the quick; +... multi=brown fox; +... name=bob smith; +multi_line.ini: e=0 user=105 +bad_multi.ini: e=1 user=105 +... [bom_section] +... bom_name=bom_value; +... key“=value“; +bom.ini: e=0 user=107 +... [section1] +... single1=abc; +... single2=xyz; +... single1=def; +... single2=qrs; +duplicate_sections.ini: e=0 user=108 +no_value.ini: e=2 user=108 diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_string.txt b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_string.txt new file mode 100644 index 00000000..4d3627f6 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/baseline_string.txt @@ -0,0 +1,21 @@ +empty string: e=0 user=0 +... [section] +... foo=bar; +... bazz=buzz quxx; +basic: e=0 user=101 +... [section] +... hello=world; +... forty_two=42; +crlf: e=0 user=102 +... [sec] +... foo=0123456789012; +... bar=4321; +long line: e=3 user=103 +... [sec] +... foo=0123456789012; +... bix=1234; +long continued: e=0 user=104 +... [s] +... a=1; +... c=3; +error: e=3 user=105 diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/bom.ini b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/bom.ini new file mode 100644 index 00000000..44c519f4 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/bom.ini @@ -0,0 +1,3 @@ +[bom_section] +bom_name=bom_value +key“ = value“ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/duplicate_sections.ini b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/duplicate_sections.ini new file mode 100644 index 00000000..68599fda --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/duplicate_sections.ini @@ -0,0 +1,6 @@ +[section1] +single1 = abc +single2 = xyz +[section1] +single1 = def +single2 = qrs \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/multi_line.ini b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/multi_line.ini new file mode 100644 index 00000000..b00f086b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/multi_line.ini @@ -0,0 +1,15 @@ +[section1] +single1 = abc +multi = this is a + multi-line value +single2 = xyz +[section2] +multi = a + b + c +[section3] +single: ghi +multi: the quick + brown fox +name = bob smith ; comment line 1 + ; comment line 2 diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/no_value.ini b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/no_value.ini new file mode 100644 index 00000000..2101ec93 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/no_value.ini @@ -0,0 +1,9 @@ +[section_list] +section0 +section1 + +[section0] +key0=val0 + +[section1] +key1=val1 diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/normal.ini b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/normal.ini new file mode 100644 index 00000000..514580ca --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/normal.ini @@ -0,0 +1,31 @@ +; This is an INI file +[section1] ; section comment +one=This is a test ; name=value comment +two = 1234 +; x=y + +[ section 2 ] +happy = 4 +sad = + +[empty] +; do nothing + +[comment_test] +test1 = 1;2;3 ; only this will be a comment +test2 = 2;3;4;this won't be a comment, needs whitespace before ';' +test;3 = 345 ; key should be "test;3" +test4 = 4#5#6 ; '#' only starts a comment at start of line +#test5 = 567 ; entire line commented + # test6 = 678 ; entire line commented, except in MULTILINE mode +test7 = ; blank value, except if inline comments disabled +test8 =; not a comment, needs whitespace before ';' + +[colon_tests] +Content-Type: text/html +foo:bar +adams : 42 +funny1 : with = equals +funny2 = with : colons +funny3 = two = equals +funny4 : two : colons diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/unittest.bat b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/unittest.bat new file mode 100644 index 00000000..b7e3e97d --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/unittest.bat @@ -0,0 +1,13 @@ +@call tcc ..\ini.c -I..\ -run unittest.c > baseline_multi.txt +@call tcc ..\ini.c -I..\ -DINI_MAX_LINE=20 -run unittest.c > baseline_multi_max_line.txt +@call tcc ..\ini.c -I..\ -DINI_ALLOW_MULTILINE=0 -run unittest.c > baseline_single.txt +@call tcc ..\ini.c -I..\ -DINI_ALLOW_INLINE_COMMENTS=0 -run unittest.c > baseline_disallow_inline_comments.txt +@call tcc ..\ini.c -I..\ -DINI_STOP_ON_FIRST_ERROR=1 -run unittest.c > baseline_stop_on_first_error.txt +@call tcc ..\ini.c -I..\ -DINI_HANDLER_LINENO=1 -run unittest.c > baseline_handler_lineno.txt +@call tcc ..\ini.c -I..\ -DINI_USE_STACK=0 -run unittest.c > baseline_heap.txt +@call tcc ..\ini.c -I..\ -DINI_USE_STACK=0 -DINI_MAX_LINE=20 -DINI_INITIAL_ALLOC=20 -run unittest.c > baseline_heap_max_line.txt +@call tcc ..\ini.c -I..\ -DINI_USE_STACK=0 -DINI_ALLOW_REALLOC=1 -DINI_INITIAL_ALLOC=5 -run unittest.c > baseline_heap_realloc.txt +@call tcc ..\ini.c -I..\ -DINI_USE_STACK=0 -DINI_MAX_LINE=20 -DINI_ALLOW_REALLOC=1 -DINI_INITIAL_ALLOC=5 -run unittest.c > baseline_heap_realloc_max_line.txt +@call tcc ..\ini.c -I..\ -DINI_USE_STACK=0 -DINI_MAX_LINE=20 -DINI_INITIAL_ALLOC=20 -run unittest.c > baseline_heap_string.txt +@call tcc ..\ini.c -I..\ -DINI_CALL_HANDLER_ON_NEW_SECTION=1 -run unittest.c > baseline_call_handler_on_new_section.txt +@call tcc ..\ini.c -I..\ -DINI_ALLOW_NO_VALUE=1 -run unittest.c > baseline_allow_no_value.txt diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/unittest.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/unittest.c new file mode 100644 index 00000000..3e85dade --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/unittest.c @@ -0,0 +1,71 @@ +/* inih -- unit tests + +This works simply by dumping a bunch of info to standard output, which is +redirected to an output file (baseline_*.txt) and checked into the Subversion +repository. This baseline file is the test output, so the idea is to check it +once, and if it changes -- look at the diff and see which tests failed. + +See unittest.bat and unittest.sh for how to run this (with tcc and gcc, +respectively). + +*/ + +#include +#include +#include +#include "../ini.h" + +int User; +char Prev_section[50]; + +#if INI_HANDLER_LINENO +int dumper(void* user, const char* section, const char* name, + const char* value, int lineno) +#else +int dumper(void* user, const char* section, const char* name, + const char* value) +#endif +{ + User = *((int*)user); + if (!name || strcmp(section, Prev_section)) { + printf("... [%s]\n", section); + strncpy(Prev_section, section, sizeof(Prev_section)); + Prev_section[sizeof(Prev_section) - 1] = '\0'; + } + if (!name) { + return 1; + } + +#if INI_HANDLER_LINENO + printf("... %s%s%s; line %d\n", name, value ? "=" : "", value ? value : "", lineno); +#else + printf("... %s%s%s;\n", name, value ? "=" : "", value ? value : ""); +#endif + + return strcmp(name, "user")==0 && strcmp(value, "parse_error")==0 ? 0 : 1; +} + +void parse(const char* fname) { + static int u = 100; + int e; + + *Prev_section = '\0'; + e = ini_parse(fname, dumper, &u); + printf("%s: e=%d user=%d\n", fname, e, User); + u++; +} + +int main(void) +{ + parse("no_file.ini"); + parse("normal.ini"); + parse("bad_section.ini"); + parse("bad_comment.ini"); + parse("user_error.ini"); + parse("multi_line.ini"); + parse("bad_multi.ini"); + parse("bom.ini"); + parse("duplicate_sections.ini"); + parse("no_value.ini"); + return 0; +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/unittest.sh b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/unittest.sh new file mode 100755 index 00000000..e01f2158 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/unittest.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +gcc ../ini.c unittest.c -o unittest_multi +./unittest_multi > baseline_multi.txt +rm -f unittest_multi + +gcc ../ini.c -DINI_MAX_LINE=20 unittest.c -o unittest_multi_max_line +./unittest_multi_max_line > baseline_multi_max_line.txt +rm -f unittest_multi_max_line + +gcc ../ini.c -DINI_ALLOW_MULTILINE=0 unittest.c -o unittest_single +./unittest_single > baseline_single.txt +rm -f unittest_single + +gcc ../ini.c -DINI_ALLOW_INLINE_COMMENTS=0 unittest.c -o unittest_disallow_inline_comments +./unittest_disallow_inline_comments > baseline_disallow_inline_comments.txt +rm -f unittest_disallow_inline_comments + +gcc ../ini.c -DINI_STOP_ON_FIRST_ERROR=1 unittest.c -o unittest_stop_on_first_error +./unittest_stop_on_first_error > baseline_stop_on_first_error.txt +rm -f unittest_stop_on_first_error + +gcc ../ini.c -DINI_HANDLER_LINENO=1 unittest.c -o unittest_handler_lineno +./unittest_handler_lineno > baseline_handler_lineno.txt +rm -f unittest_handler_lineno + +gcc ../ini.c -DINI_MAX_LINE=20 unittest_string.c -o unittest_string +./unittest_string > baseline_string.txt +rm -f unittest_string + +gcc ../ini.c -DINI_USE_STACK=0 unittest.c -o unittest_heap +./unittest_heap > baseline_heap.txt +rm -f unittest_heap + +gcc ../ini.c -DINI_USE_STACK=0 -DINI_MAX_LINE=20 -DINI_INITIAL_ALLOC=20 unittest.c -o unittest_heap_max_line +./unittest_heap_max_line > baseline_heap_max_line.txt +rm -f unittest_heap_max_line + +gcc ../ini.c -DINI_USE_STACK=0 -DINI_ALLOW_REALLOC=1 -DINI_INITIAL_ALLOC=5 unittest.c -o unittest_heap_realloc +./unittest_heap_realloc > baseline_heap_realloc.txt +rm -f unittest_heap_realloc + +gcc ../ini.c -DINI_USE_STACK=0 -DINI_MAX_LINE=20 -DINI_ALLOW_REALLOC=1 -DINI_INITIAL_ALLOC=5 unittest.c -o unittest_heap_realloc_max_line +./unittest_heap_realloc_max_line > baseline_heap_realloc_max_line.txt +rm -f unittest_heap_realloc_max_line + +gcc ../ini.c -DINI_USE_STACK=0 -DINI_MAX_LINE=20 -DINI_INITIAL_ALLOC=20 unittest_string.c -o unittest_heap_string +./unittest_heap_string > baseline_heap_string.txt +rm -f unittest_heap_string + +gcc ../ini.c -DINI_CALL_HANDLER_ON_NEW_SECTION=1 unittest.c -o unittest_call_handler_on_new_section +./unittest_call_handler_on_new_section > baseline_call_handler_on_new_section.txt +rm -f unittest_call_handler_on_new_section + +gcc ../ini.c -DINI_ALLOW_NO_VALUE=1 unittest.c -o unittest_allow_no_value +./unittest_allow_no_value > baseline_allow_no_value.txt +rm -f unittest_allow_no_value diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/unittest_string.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/unittest_string.c new file mode 100644 index 00000000..4200e6b7 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/unittest_string.c @@ -0,0 +1,43 @@ +/* inih -- unit tests for ini_parse_string() */ + +#include +#include +#include +#include "../ini.h" + +int User; +char Prev_section[50]; + +int dumper(void* user, const char* section, const char* name, + const char* value) +{ + User = *((int*)user); + if (strcmp(section, Prev_section)) { + printf("... [%s]\n", section); + strncpy(Prev_section, section, sizeof(Prev_section)); + Prev_section[sizeof(Prev_section) - 1] = '\0'; + } + printf("... %s=%s;\n", name, value); + return 1; +} + +void parse(const char* name, const char* string) { + static int u = 100; + int e; + + *Prev_section = '\0'; + e = ini_parse_string(string, dumper, &u); + printf("%s: e=%d user=%d\n", name, e, User); + u++; +} + +int main(void) +{ + parse("empty string", ""); + parse("basic", "[section]\nfoo = bar\nbazz = buzz quxx"); + parse("crlf", "[section]\r\nhello = world\r\nforty_two = 42\r\n"); + parse("long line", "[sec]\nfoo = 01234567890123456789\nbar=4321\n"); + parse("long continued", "[sec]\nfoo = 0123456789012bix=1234\n"); + parse("error", "[s]\na=1\nb\nc=3"); + return 0; +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/user_error.ini b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/user_error.ini new file mode 100644 index 00000000..65963878 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/inih/tests/user_error.ini @@ -0,0 +1,4 @@ +[section] +a = b +user = parse_error +c = d diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/stb/stb_image.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/stb/stb_image.h new file mode 100644 index 00000000..2857f05d --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/stb/stb_image.h @@ -0,0 +1,7656 @@ +/* stb_image - v2.25 - public domain image loader - http://nothings.org/stb + no warranty implied; use at your own risk + + Do this: + #define STB_IMAGE_IMPLEMENTATION + before you include this file in *one* C or C++ file to create the implementation. + + // i.e. it should look like this: + #include ... + #include ... + #include ... + #define STB_IMAGE_IMPLEMENTATION + #include "stb_image.h" + + You can #define STBI_ASSERT(x) before the #include to avoid using assert.h. + And #define STBI_MALLOC, STBI_REALLOC, and STBI_FREE to avoid using malloc,realloc,free + + + QUICK NOTES: + Primarily of interest to game developers and other people who can + avoid problematic images and only need the trivial interface + + JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib) + PNG 1/2/4/8/16-bit-per-channel + + TGA (not sure what subset, if a subset) + BMP non-1bpp, non-RLE + PSD (composited view only, no extra channels, 8/16 bit-per-channel) + + GIF (*comp always reports as 4-channel) + HDR (radiance rgbE format) + PIC (Softimage PIC) + PNM (PPM and PGM binary only) + + Animated GIF still needs a proper API, but here's one way to do it: + http://gist.github.com/urraka/685d9a6340b26b830d49 + + - decode from memory or through FILE (define STBI_NO_STDIO to remove code) + - decode from arbitrary I/O callbacks + - SIMD acceleration on x86/x64 (SSE2) and ARM (NEON) + + Full documentation under "DOCUMENTATION" below. + + +LICENSE + + See end of file for license information. + +RECENT REVISION HISTORY: + + 2.25 (2020-02-02) fix warnings + 2.24 (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically + 2.23 (2019-08-11) fix clang static analysis warning + 2.22 (2019-03-04) gif fixes, fix warnings + 2.21 (2019-02-25) fix typo in comment + 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs + 2.19 (2018-02-11) fix warning + 2.18 (2018-01-30) fix warnings + 2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings + 2.16 (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes + 2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC + 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs + 2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes + 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes + 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64 + RGB-format JPEG; remove white matting in PSD; + allocate large structures on the stack; + correct channel count for PNG & BMP + 2.10 (2016-01-22) avoid warning introduced in 2.09 + 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED + + See end of file for full revision history. + + + ============================ Contributors ========================= + + Image formats Extensions, features + Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info) + Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info) + Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG) + Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks) + Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG) + Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip) + Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD) + github:urraka (animated gif) Junggon Kim (PNM comments) + Christopher Forseth (animated gif) Daniel Gibson (16-bit TGA) + socks-the-fox (16-bit PNG) + Jeremy Sawicki (handle all ImageNet JPGs) + Optimizations & bugfixes Mikhail Morozov (1-bit BMP) + Fabian "ryg" Giesen Anael Seghezzi (is-16-bit query) + Arseny Kapoulkine + John-Mark Allen + Carmelo J Fdez-Aguera + + Bug & warning fixes + Marc LeBlanc David Woo Guillaume George Martins Mozeiko + Christpher Lloyd Jerry Jansson Joseph Thomson Phil Jordan + Dave Moore Roy Eltham Hayaki Saito Nathan Reed + Won Chun Luke Graham Johan Duparc Nick Verigakis + the Horde3D community Thomas Ruf Ronny Chevalier github:rlyeh + Janez Zemva John Bartholomew Michal Cichon github:romigrou + Jonathan Blow Ken Hamada Tero Hanninen github:svdijk + Laurent Gomila Cort Stratton Sergio Gonzalez github:snagar + Aruelien Pocheville Thibault Reuille Cass Everitt github:Zelex + Ryamond Barbiero Paul Du Bois Engin Manap github:grim210 + Aldo Culquicondor Philipp Wiesemann Dale Weiler github:sammyhw + Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus + Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo + Christian Floisand Kevin Schmidt JR Smith github:darealshinji + Brad Weinberger Matvey Cherevko github:Michaelangel007 + Blazej Dariusz Roszkowski Alexander Veselov +*/ + +#ifndef STBI_INCLUDE_STB_IMAGE_H +#define STBI_INCLUDE_STB_IMAGE_H + +// DOCUMENTATION +// +// Limitations: +// - no 12-bit-per-channel JPEG +// - no JPEGs with arithmetic coding +// - GIF always returns *comp=4 +// +// Basic usage (see HDR discussion below for HDR usage): +// int x,y,n; +// unsigned char *data = stbi_load(filename, &x, &y, &n, 0); +// // ... process data if not NULL ... +// // ... x = width, y = height, n = # 8-bit components per pixel ... +// // ... replace '0' with '1'..'4' to force that many components per pixel +// // ... but 'n' will always be the number that it would have been if you said 0 +// stbi_image_free(data) +// +// Standard parameters: +// int *x -- outputs image width in pixels +// int *y -- outputs image height in pixels +// int *channels_in_file -- outputs # of image components in image file +// int desired_channels -- if non-zero, # of image components requested in result +// +// The return value from an image loader is an 'unsigned char *' which points +// to the pixel data, or NULL on an allocation failure or if the image is +// corrupt or invalid. The pixel data consists of *y scanlines of *x pixels, +// with each pixel consisting of N interleaved 8-bit components; the first +// pixel pointed to is top-left-most in the image. There is no padding between +// image scanlines or between pixels, regardless of format. The number of +// components N is 'desired_channels' if desired_channels is non-zero, or +// *channels_in_file otherwise. If desired_channels is non-zero, +// *channels_in_file has the number of components that _would_ have been +// output otherwise. E.g. if you set desired_channels to 4, you will always +// get RGBA output, but you can check *channels_in_file to see if it's trivially +// opaque because e.g. there were only 3 channels in the source image. +// +// An output image with N components has the following components interleaved +// in this order in each pixel: +// +// N=#comp components +// 1 grey +// 2 grey, alpha +// 3 red, green, blue +// 4 red, green, blue, alpha +// +// If image loading fails for any reason, the return value will be NULL, +// and *x, *y, *channels_in_file will be unchanged. The function +// stbi_failure_reason() can be queried for an extremely brief, end-user +// unfriendly explanation of why the load failed. Define STBI_NO_FAILURE_STRINGS +// to avoid compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly +// more user-friendly ones. +// +// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized. +// +// =========================================================================== +// +// UNICODE: +// +// If compiling for Windows and you wish to use Unicode filenames, compile +// with +// #define STBI_WINDOWS_UTF8 +// and pass utf8-encoded filenames. Call stbi_convert_wchar_to_utf8 to convert +// Windows wchar_t filenames to utf8. +// +// =========================================================================== +// +// Philosophy +// +// stb libraries are designed with the following priorities: +// +// 1. easy to use +// 2. easy to maintain +// 3. good performance +// +// Sometimes I let "good performance" creep up in priority over "easy to maintain", +// and for best performance I may provide less-easy-to-use APIs that give higher +// performance, in addition to the easy-to-use ones. Nevertheless, it's important +// to keep in mind that from the standpoint of you, a client of this library, +// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all. +// +// Some secondary priorities arise directly from the first two, some of which +// provide more explicit reasons why performance can't be emphasized. +// +// - Portable ("ease of use") +// - Small source code footprint ("easy to maintain") +// - No dependencies ("ease of use") +// +// =========================================================================== +// +// I/O callbacks +// +// I/O callbacks allow you to read from arbitrary sources, like packaged +// files or some other source. Data read from callbacks are processed +// through a small internal buffer (currently 128 bytes) to try to reduce +// overhead. +// +// The three functions you must define are "read" (reads some bytes of data), +// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). +// +// =========================================================================== +// +// SIMD support +// +// The JPEG decoder will try to automatically use SIMD kernels on x86 when +// supported by the compiler. For ARM Neon support, you must explicitly +// request it. +// +// (The old do-it-yourself SIMD API is no longer supported in the current +// code.) +// +// On x86, SSE2 will automatically be used when available based on a run-time +// test; if not, the generic C versions are used as a fall-back. On ARM targets, +// the typical path is to have separate builds for NEON and non-NEON devices +// (at least this is true for iOS and Android). Therefore, the NEON support is +// toggled by a build flag: define STBI_NEON to get NEON loops. +// +// If for some reason you do not want to use any of SIMD code, or if +// you have issues compiling it, you can disable it entirely by +// defining STBI_NO_SIMD. +// +// =========================================================================== +// +// HDR image support (disable by defining STBI_NO_HDR) +// +// stb_image supports loading HDR images in general, and currently the Radiance +// .HDR file format specifically. You can still load any file through the existing +// interface; if you attempt to load an HDR file, it will be automatically remapped +// to LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1; +// both of these constants can be reconfigured through this interface: +// +// stbi_hdr_to_ldr_gamma(2.2f); +// stbi_hdr_to_ldr_scale(1.0f); +// +// (note, do not use _inverse_ constants; stbi_image will invert them +// appropriately). +// +// Additionally, there is a new, parallel interface for loading files as +// (linear) floats to preserve the full dynamic range: +// +// float *data = stbi_loadf(filename, &x, &y, &n, 0); +// +// If you load LDR images through this interface, those images will +// be promoted to floating point values, run through the inverse of +// constants corresponding to the above: +// +// stbi_ldr_to_hdr_scale(1.0f); +// stbi_ldr_to_hdr_gamma(2.2f); +// +// Finally, given a filename (or an open file or memory block--see header +// file for details) containing image data, you can query for the "most +// appropriate" interface to use (that is, whether the image is HDR or +// not), using: +// +// stbi_is_hdr(char *filename); +// +// =========================================================================== +// +// iPhone PNG support: +// +// By default we convert iphone-formatted PNGs back to RGB, even though +// they are internally encoded differently. You can disable this conversion +// by calling stbi_convert_iphone_png_to_rgb(0), in which case +// you will always just get the native iphone "format" through (which +// is BGR stored in RGB). +// +// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per +// pixel to remove any premultiplied alpha *only* if the image file explicitly +// says there's premultiplied data (currently only happens in iPhone images, +// and only if iPhone convert-to-rgb processing is on). +// +// =========================================================================== +// +// ADDITIONAL CONFIGURATION +// +// - You can suppress implementation of any of the decoders to reduce +// your code footprint by #defining one or more of the following +// symbols before creating the implementation. +// +// STBI_NO_JPEG +// STBI_NO_PNG +// STBI_NO_BMP +// STBI_NO_PSD +// STBI_NO_TGA +// STBI_NO_GIF +// STBI_NO_HDR +// STBI_NO_PIC +// STBI_NO_PNM (.ppm and .pgm) +// +// - You can request *only* certain decoders and suppress all other ones +// (this will be more forward-compatible, as addition of new decoders +// doesn't require you to disable them explicitly): +// +// STBI_ONLY_JPEG +// STBI_ONLY_PNG +// STBI_ONLY_BMP +// STBI_ONLY_PSD +// STBI_ONLY_TGA +// STBI_ONLY_GIF +// STBI_ONLY_HDR +// STBI_ONLY_PIC +// STBI_ONLY_PNM (.ppm and .pgm) +// +// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still +// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB +// + + +#ifndef STBI_NO_STDIO +#include +#endif // STBI_NO_STDIO + +#define STBI_VERSION 1 + +enum +{ + STBI_default = 0, // only used for desired_channels + + STBI_grey = 1, + STBI_grey_alpha = 2, + STBI_rgb = 3, + STBI_rgb_alpha = 4 +}; + +#include +typedef unsigned char stbi_uc; +typedef unsigned short stbi_us; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef STBIDEF +#ifdef STB_IMAGE_STATIC +#define STBIDEF static +#else +#define STBIDEF extern +#endif +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// PRIMARY API - works on images of any type +// + +// +// load image by filename, open file, or memory buffer +// + +typedef struct +{ + int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read + void (*skip) (void *user,int n); // skip the next 'n' bytes, or 'unget' the last -n bytes if negative + int (*eof) (void *user); // returns nonzero if we are at end of file/data +} stbi_io_callbacks; + +//////////////////////////////////// +// +// 8-bits-per-channel interface +// + +STBIDEF stbi_uc *stbi_load_from_memory (stbi_uc const *buffer, int len , int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk , void *user, int *x, int *y, int *channels_in_file, int desired_channels); + +#ifndef STBI_NO_STDIO +STBIDEF stbi_uc *stbi_load (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); +// for stbi_load_from_file, file pointer is left pointing immediately after image +#endif + +#ifndef STBI_NO_GIF +STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp); +#endif + +#ifdef STBI_WINDOWS_UTF8 +STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input); +#endif + +//////////////////////////////////// +// +// 16-bits-per-channel interface +// + +STBIDEF stbi_us *stbi_load_16_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); + +#ifndef STBI_NO_STDIO +STBIDEF stbi_us *stbi_load_16 (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); +STBIDEF stbi_us *stbi_load_from_file_16(FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); +#endif + +//////////////////////////////////// +// +// float-per-channel interface +// +#ifndef STBI_NO_LINEAR + STBIDEF float *stbi_loadf_from_memory (stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels); + + #ifndef STBI_NO_STDIO + STBIDEF float *stbi_loadf (char const *filename, int *x, int *y, int *channels_in_file, int desired_channels); + STBIDEF float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *channels_in_file, int desired_channels); + #endif +#endif + +#ifndef STBI_NO_HDR + STBIDEF void stbi_hdr_to_ldr_gamma(float gamma); + STBIDEF void stbi_hdr_to_ldr_scale(float scale); +#endif // STBI_NO_HDR + +#ifndef STBI_NO_LINEAR + STBIDEF void stbi_ldr_to_hdr_gamma(float gamma); + STBIDEF void stbi_ldr_to_hdr_scale(float scale); +#endif // STBI_NO_LINEAR + +// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); +STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); +#ifndef STBI_NO_STDIO +STBIDEF int stbi_is_hdr (char const *filename); +STBIDEF int stbi_is_hdr_from_file(FILE *f); +#endif // STBI_NO_STDIO + + +// get a VERY brief reason for failure +// on most compilers (and ALL modern mainstream compilers) this is threadsafe +STBIDEF const char *stbi_failure_reason (void); + +// free the loaded image -- this is just free() +STBIDEF void stbi_image_free (void *retval_from_stbi_load); + +// get image dimensions & components without fully decoding +STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); +STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); +STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len); +STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *clbk, void *user); + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_info (char const *filename, int *x, int *y, int *comp); +STBIDEF int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); +STBIDEF int stbi_is_16_bit (char const *filename); +STBIDEF int stbi_is_16_bit_from_file(FILE *f); +#endif + + + +// for image formats that explicitly notate that they have premultiplied alpha, +// we just return the colors as stored in the file. set this flag to force +// unpremultiplication. results are undefined if the unpremultiply overflow. +STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); + +// indicate whether we should process iphone images back to canonical format, +// or just pass them through "as-is" +STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); + +// flip the image vertically, so the first pixel in the output array is the bottom left +STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip); + +// as above, but only applies to images loaded on the thread that calls the function +// this function is only available if your compiler supports thread-local variables; +// calling it will fail to link if your compiler doesn't +STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip); + +// ZLIB client - used by PNG, available for other purposes + +STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); +STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header); +STBIDEF char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); +STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + +STBIDEF char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); +STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + + +#ifdef __cplusplus +} +#endif + +// +// +//// end header file ///////////////////////////////////////////////////// +#endif // STBI_INCLUDE_STB_IMAGE_H + +#ifdef STB_IMAGE_IMPLEMENTATION + +#if defined(STBI_ONLY_JPEG) || defined(STBI_ONLY_PNG) || defined(STBI_ONLY_BMP) \ + || defined(STBI_ONLY_TGA) || defined(STBI_ONLY_GIF) || defined(STBI_ONLY_PSD) \ + || defined(STBI_ONLY_HDR) || defined(STBI_ONLY_PIC) || defined(STBI_ONLY_PNM) \ + || defined(STBI_ONLY_ZLIB) + #ifndef STBI_ONLY_JPEG + #define STBI_NO_JPEG + #endif + #ifndef STBI_ONLY_PNG + #define STBI_NO_PNG + #endif + #ifndef STBI_ONLY_BMP + #define STBI_NO_BMP + #endif + #ifndef STBI_ONLY_PSD + #define STBI_NO_PSD + #endif + #ifndef STBI_ONLY_TGA + #define STBI_NO_TGA + #endif + #ifndef STBI_ONLY_GIF + #define STBI_NO_GIF + #endif + #ifndef STBI_ONLY_HDR + #define STBI_NO_HDR + #endif + #ifndef STBI_ONLY_PIC + #define STBI_NO_PIC + #endif + #ifndef STBI_ONLY_PNM + #define STBI_NO_PNM + #endif +#endif + +#if defined(STBI_NO_PNG) && !defined(STBI_SUPPORT_ZLIB) && !defined(STBI_NO_ZLIB) +#define STBI_NO_ZLIB +#endif + + +#include +#include // ptrdiff_t on osx +#include +#include +#include + +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) +#include // ldexp, pow +#endif + +#ifndef STBI_NO_STDIO +#include +#endif + +#ifndef STBI_ASSERT +#include +#define STBI_ASSERT(x) assert(x) +#endif + +#ifdef __cplusplus +#define STBI_EXTERN extern "C" +#else +#define STBI_EXTERN extern +#endif + + +#ifndef _MSC_VER + #ifdef __cplusplus + #define stbi_inline inline + #else + #define stbi_inline + #endif +#else + #define stbi_inline __forceinline +#endif + +#ifndef STBI_NO_THREAD_LOCALS + #if defined(__cplusplus) && __cplusplus >= 201103L + #define STBI_THREAD_LOCAL thread_local + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L + #define STBI_THREAD_LOCAL _Thread_local + #elif defined(__GNUC__) + #define STBI_THREAD_LOCAL __thread + #elif defined(_MSC_VER) + #define STBI_THREAD_LOCAL __declspec(thread) +#endif +#endif + +#ifdef _MSC_VER +typedef unsigned short stbi__uint16; +typedef signed short stbi__int16; +typedef unsigned int stbi__uint32; +typedef signed int stbi__int32; +#else +#include +typedef uint16_t stbi__uint16; +typedef int16_t stbi__int16; +typedef uint32_t stbi__uint32; +typedef int32_t stbi__int32; +#endif + +// should produce compiler error if size is wrong +typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1]; + +#ifdef _MSC_VER +#define STBI_NOTUSED(v) (void)(v) +#else +#define STBI_NOTUSED(v) (void)sizeof(v) +#endif + +#ifdef _MSC_VER +#define STBI_HAS_LROTL +#endif + +#ifdef STBI_HAS_LROTL + #define stbi_lrot(x,y) _lrotl(x,y) +#else + #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) +#endif + +#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED)) +// ok +#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED) +// ok +#else +#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)." +#endif + +#ifndef STBI_MALLOC +#define STBI_MALLOC(sz) malloc(sz) +#define STBI_REALLOC(p,newsz) realloc(p,newsz) +#define STBI_FREE(p) free(p) +#endif + +#ifndef STBI_REALLOC_SIZED +#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz) +#endif + +// x86/x64 detection +#if defined(__x86_64__) || defined(_M_X64) +#define STBI__X64_TARGET +#elif defined(__i386) || defined(_M_IX86) +#define STBI__X86_TARGET +#endif + +#if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD) +// gcc doesn't support sse2 intrinsics unless you compile with -msse2, +// which in turn means it gets to use SSE2 everywhere. This is unfortunate, +// but previous attempts to provide the SSE2 functions with runtime +// detection caused numerous issues. The way architecture extensions are +// exposed in GCC/Clang is, sadly, not really suited for one-file libs. +// New behavior: if compiled with -msse2, we use SSE2 without any +// detection; if not, we don't use it at all. +#define STBI_NO_SIMD +#endif + +#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD) +// Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET +// +// 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the +// Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant. +// As a result, enabling SSE2 on 32-bit MinGW is dangerous when not +// simultaneously enabling "-mstackrealign". +// +// See https://github.com/nothings/stb/issues/81 for more information. +// +// So default to no SSE2 on 32-bit MinGW. If you've read this far and added +// -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2. +#define STBI_NO_SIMD +#endif + +#if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) +#define STBI_SSE2 +#include + +#ifdef _MSC_VER + +#if _MSC_VER >= 1400 // not VC6 +#include // __cpuid +static int stbi__cpuid3(void) +{ + int info[4]; + __cpuid(info,1); + return info[3]; +} +#else +static int stbi__cpuid3(void) +{ + int res; + __asm { + mov eax,1 + cpuid + mov res,edx + } + return res; +} +#endif + +#define STBI_SIMD_ALIGN(type, name) __declspec(align(16)) type name + +#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2) +static int stbi__sse2_available(void) +{ + int info3 = stbi__cpuid3(); + return ((info3 >> 26) & 1) != 0; +} +#endif + +#else // assume GCC-style if not VC++ +#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) + +#if !defined(STBI_NO_JPEG) && defined(STBI_SSE2) +static int stbi__sse2_available(void) +{ + // If we're even attempting to compile this on GCC/Clang, that means + // -msse2 is on, which means the compiler is allowed to use SSE2 + // instructions at will, and so are we. + return 1; +} +#endif + +#endif +#endif + +// ARM NEON +#if defined(STBI_NO_SIMD) && defined(STBI_NEON) +#undef STBI_NEON +#endif + +#ifdef STBI_NEON +#include +// assume GCC or Clang on ARM targets +#define STBI_SIMD_ALIGN(type, name) type name __attribute__((aligned(16))) +#endif + +#ifndef STBI_SIMD_ALIGN +#define STBI_SIMD_ALIGN(type, name) type name +#endif + +/////////////////////////////////////////////// +// +// stbi__context struct and start_xxx functions + +// stbi__context structure is our basic context used by all images, so it +// contains all the IO context, plus some basic image information +typedef struct +{ + stbi__uint32 img_x, img_y; + int img_n, img_out_n; + + stbi_io_callbacks io; + void *io_user_data; + + int read_from_callbacks; + int buflen; + stbi_uc buffer_start[128]; + + stbi_uc *img_buffer, *img_buffer_end; + stbi_uc *img_buffer_original, *img_buffer_original_end; +} stbi__context; + + +static void stbi__refill_buffer(stbi__context *s); + +// initialize a memory-decode context +static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len) +{ + s->io.read = NULL; + s->read_from_callbacks = 0; + s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer; + s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len; +} + +// initialize a callback-based context +static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *user) +{ + s->io = *c; + s->io_user_data = user; + s->buflen = sizeof(s->buffer_start); + s->read_from_callbacks = 1; + s->img_buffer_original = s->buffer_start; + stbi__refill_buffer(s); + s->img_buffer_original_end = s->img_buffer_end; +} + +#ifndef STBI_NO_STDIO + +static int stbi__stdio_read(void *user, char *data, int size) +{ + return (int) fread(data,1,size,(FILE*) user); +} + +static void stbi__stdio_skip(void *user, int n) +{ + fseek((FILE*) user, n, SEEK_CUR); +} + +static int stbi__stdio_eof(void *user) +{ + return feof((FILE*) user); +} + +static stbi_io_callbacks stbi__stdio_callbacks = +{ + stbi__stdio_read, + stbi__stdio_skip, + stbi__stdio_eof, +}; + +static void stbi__start_file(stbi__context *s, FILE *f) +{ + stbi__start_callbacks(s, &stbi__stdio_callbacks, (void *) f); +} + +//static void stop_file(stbi__context *s) { } + +#endif // !STBI_NO_STDIO + +static void stbi__rewind(stbi__context *s) +{ + // conceptually rewind SHOULD rewind to the beginning of the stream, + // but we just rewind to the beginning of the initial buffer, because + // we only use it after doing 'test', which only ever looks at at most 92 bytes + s->img_buffer = s->img_buffer_original; + s->img_buffer_end = s->img_buffer_original_end; +} + +enum +{ + STBI_ORDER_RGB, + STBI_ORDER_BGR +}; + +typedef struct +{ + int bits_per_channel; + int num_channels; + int channel_order; +} stbi__result_info; + +#ifndef STBI_NO_JPEG +static int stbi__jpeg_test(stbi__context *s); +static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PNG +static int stbi__png_test(stbi__context *s); +static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__png_is16(stbi__context *s); +#endif + +#ifndef STBI_NO_BMP +static int stbi__bmp_test(stbi__context *s); +static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_TGA +static int stbi__tga_test(stbi__context *s); +static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PSD +static int stbi__psd_test(stbi__context *s); +static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc); +static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp); +static int stbi__psd_is16(stbi__context *s); +#endif + +#ifndef STBI_NO_HDR +static int stbi__hdr_test(stbi__context *s); +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PIC +static int stbi__pic_test(stbi__context *s); +static void *stbi__pic_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_GIF +static int stbi__gif_test(stbi__context *s); +static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp); +static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +#ifndef STBI_NO_PNM +static int stbi__pnm_test(stbi__context *s); +static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri); +static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp); +#endif + +static +#ifdef STBI_THREAD_LOCAL +STBI_THREAD_LOCAL +#endif +const char *stbi__g_failure_reason; + +STBIDEF const char *stbi_failure_reason(void) +{ + return stbi__g_failure_reason; +} + +#ifndef STBI_NO_FAILURE_STRINGS +static int stbi__err(const char *str) +{ + stbi__g_failure_reason = str; + return 0; +} +#endif + +static void *stbi__malloc(size_t size) +{ + return STBI_MALLOC(size); +} + +// stb_image uses ints pervasively, including for offset calculations. +// therefore the largest decoded image size we can support with the +// current code, even on 64-bit targets, is INT_MAX. this is not a +// significant limitation for the intended use case. +// +// we do, however, need to make sure our size calculations don't +// overflow. hence a few helper functions for size calculations that +// multiply integers together, making sure that they're non-negative +// and no overflow occurs. + +// return 1 if the sum is valid, 0 on overflow. +// negative terms are considered invalid. +static int stbi__addsizes_valid(int a, int b) +{ + if (b < 0) return 0; + // now 0 <= b <= INT_MAX, hence also + // 0 <= INT_MAX - b <= INTMAX. + // And "a + b <= INT_MAX" (which might overflow) is the + // same as a <= INT_MAX - b (no overflow) + return a <= INT_MAX - b; +} + +// returns 1 if the product is valid, 0 on overflow. +// negative factors are considered invalid. +static int stbi__mul2sizes_valid(int a, int b) +{ + if (a < 0 || b < 0) return 0; + if (b == 0) return 1; // mul-by-0 is always safe + // portable way to check for no overflows in a*b + return a <= INT_MAX/b; +} + +#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) +// returns 1 if "a*b + add" has no negative terms/factors and doesn't overflow +static int stbi__mad2sizes_valid(int a, int b, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__addsizes_valid(a*b, add); +} +#endif + +// returns 1 if "a*b*c + add" has no negative terms/factors and doesn't overflow +static int stbi__mad3sizes_valid(int a, int b, int c, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && + stbi__addsizes_valid(a*b*c, add); +} + +// returns 1 if "a*b*c*d + add" has no negative terms/factors and doesn't overflow +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) +static int stbi__mad4sizes_valid(int a, int b, int c, int d, int add) +{ + return stbi__mul2sizes_valid(a, b) && stbi__mul2sizes_valid(a*b, c) && + stbi__mul2sizes_valid(a*b*c, d) && stbi__addsizes_valid(a*b*c*d, add); +} +#endif + +#if !defined(STBI_NO_JPEG) || !defined(STBI_NO_PNG) || !defined(STBI_NO_TGA) || !defined(STBI_NO_HDR) +// mallocs with size overflow checking +static void *stbi__malloc_mad2(int a, int b, int add) +{ + if (!stbi__mad2sizes_valid(a, b, add)) return NULL; + return stbi__malloc(a*b + add); +} +#endif + +static void *stbi__malloc_mad3(int a, int b, int c, int add) +{ + if (!stbi__mad3sizes_valid(a, b, c, add)) return NULL; + return stbi__malloc(a*b*c + add); +} + +#if !defined(STBI_NO_LINEAR) || !defined(STBI_NO_HDR) +static void *stbi__malloc_mad4(int a, int b, int c, int d, int add) +{ + if (!stbi__mad4sizes_valid(a, b, c, d, add)) return NULL; + return stbi__malloc(a*b*c*d + add); +} +#endif + +// stbi__err - error +// stbi__errpf - error returning pointer to float +// stbi__errpuc - error returning pointer to unsigned char + +#ifdef STBI_NO_FAILURE_STRINGS + #define stbi__err(x,y) 0 +#elif defined(STBI_FAILURE_USERMSG) + #define stbi__err(x,y) stbi__err(y) +#else + #define stbi__err(x,y) stbi__err(x) +#endif + +#define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL)) +#define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL)) + +STBIDEF void stbi_image_free(void *retval_from_stbi_load) +{ + STBI_FREE(retval_from_stbi_load); +} + +#ifndef STBI_NO_LINEAR +static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp); +#endif + +#ifndef STBI_NO_HDR +static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp); +#endif + +static int stbi__vertically_flip_on_load_global = 0; + +STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) +{ + stbi__vertically_flip_on_load_global = flag_true_if_should_flip; +} + +#ifndef STBI_THREAD_LOCAL +#define stbi__vertically_flip_on_load stbi__vertically_flip_on_load_global +#else +static STBI_THREAD_LOCAL int stbi__vertically_flip_on_load_local, stbi__vertically_flip_on_load_set; + +STBIDEF void stbi_set_flip_vertically_on_load_thread(int flag_true_if_should_flip) +{ + stbi__vertically_flip_on_load_local = flag_true_if_should_flip; + stbi__vertically_flip_on_load_set = 1; +} + +#define stbi__vertically_flip_on_load (stbi__vertically_flip_on_load_set \ + ? stbi__vertically_flip_on_load_local \ + : stbi__vertically_flip_on_load_global) +#endif // STBI_THREAD_LOCAL + +static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) +{ + memset(ri, 0, sizeof(*ri)); // make sure it's initialized if we add new fields + ri->bits_per_channel = 8; // default is 8 so most paths don't have to be changed + ri->channel_order = STBI_ORDER_RGB; // all current input & output are this, but this is here so we can add BGR order + ri->num_channels = 0; + + #ifndef STBI_NO_JPEG + if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_PNG + if (stbi__png_test(s)) return stbi__png_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_BMP + if (stbi__bmp_test(s)) return stbi__bmp_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_GIF + if (stbi__gif_test(s)) return stbi__gif_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_PSD + if (stbi__psd_test(s)) return stbi__psd_load(s,x,y,comp,req_comp, ri, bpc); + #else + STBI_NOTUSED(bpc); + #endif + #ifndef STBI_NO_PIC + if (stbi__pic_test(s)) return stbi__pic_load(s,x,y,comp,req_comp, ri); + #endif + #ifndef STBI_NO_PNM + if (stbi__pnm_test(s)) return stbi__pnm_load(s,x,y,comp,req_comp, ri); + #endif + + #ifndef STBI_NO_HDR + if (stbi__hdr_test(s)) { + float *hdr = stbi__hdr_load(s, x,y,comp,req_comp, ri); + return stbi__hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); + } + #endif + + #ifndef STBI_NO_TGA + // test tga last because it's a crappy test! + if (stbi__tga_test(s)) + return stbi__tga_load(s,x,y,comp,req_comp, ri); + #endif + + return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt"); +} + +static stbi_uc *stbi__convert_16_to_8(stbi__uint16 *orig, int w, int h, int channels) +{ + int i; + int img_len = w * h * channels; + stbi_uc *reduced; + + reduced = (stbi_uc *) stbi__malloc(img_len); + if (reduced == NULL) return stbi__errpuc("outofmem", "Out of memory"); + + for (i = 0; i < img_len; ++i) + reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is sufficient approx of 16->8 bit scaling + + STBI_FREE(orig); + return reduced; +} + +static stbi__uint16 *stbi__convert_8_to_16(stbi_uc *orig, int w, int h, int channels) +{ + int i; + int img_len = w * h * channels; + stbi__uint16 *enlarged; + + enlarged = (stbi__uint16 *) stbi__malloc(img_len*2); + if (enlarged == NULL) return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); + + for (i = 0; i < img_len; ++i) + enlarged[i] = (stbi__uint16)((orig[i] << 8) + orig[i]); // replicate to high and low byte, maps 0->0, 255->0xffff + + STBI_FREE(orig); + return enlarged; +} + +static void stbi__vertical_flip(void *image, int w, int h, int bytes_per_pixel) +{ + int row; + size_t bytes_per_row = (size_t)w * bytes_per_pixel; + stbi_uc temp[2048]; + stbi_uc *bytes = (stbi_uc *)image; + + for (row = 0; row < (h>>1); row++) { + stbi_uc *row0 = bytes + row*bytes_per_row; + stbi_uc *row1 = bytes + (h - row - 1)*bytes_per_row; + // swap row0 with row1 + size_t bytes_left = bytes_per_row; + while (bytes_left) { + size_t bytes_copy = (bytes_left < sizeof(temp)) ? bytes_left : sizeof(temp); + memcpy(temp, row0, bytes_copy); + memcpy(row0, row1, bytes_copy); + memcpy(row1, temp, bytes_copy); + row0 += bytes_copy; + row1 += bytes_copy; + bytes_left -= bytes_copy; + } + } +} + +#ifndef STBI_NO_GIF +static void stbi__vertical_flip_slices(void *image, int w, int h, int z, int bytes_per_pixel) +{ + int slice; + int slice_size = w * h * bytes_per_pixel; + + stbi_uc *bytes = (stbi_uc *)image; + for (slice = 0; slice < z; ++slice) { + stbi__vertical_flip(bytes, w, h, bytes_per_pixel); + bytes += slice_size; + } +} +#endif + +static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi__result_info ri; + void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 8); + + if (result == NULL) + return NULL; + + if (ri.bits_per_channel != 8) { + STBI_ASSERT(ri.bits_per_channel == 16); + result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp); + ri.bits_per_channel = 8; + } + + // @TODO: move stbi__convert_format to here + + if (stbi__vertically_flip_on_load) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi_uc)); + } + + return (unsigned char *) result; +} + +static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + stbi__result_info ri; + void *result = stbi__load_main(s, x, y, comp, req_comp, &ri, 16); + + if (result == NULL) + return NULL; + + if (ri.bits_per_channel != 16) { + STBI_ASSERT(ri.bits_per_channel == 8); + result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp); + ri.bits_per_channel = 16; + } + + // @TODO: move stbi__convert_format16 to here + // @TODO: special case RGB-to-Y (and RGBA-to-YA) for 8-bit-to-16-bit case to keep more precision + + if (stbi__vertically_flip_on_load) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(stbi__uint16)); + } + + return (stbi__uint16 *) result; +} + +#if !defined(STBI_NO_HDR) && !defined(STBI_NO_LINEAR) +static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp) +{ + if (stbi__vertically_flip_on_load && result != NULL) { + int channels = req_comp ? req_comp : *comp; + stbi__vertical_flip(result, *x, *y, channels * sizeof(float)); + } +} +#endif + +#ifndef STBI_NO_STDIO + +#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) +STBI_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide); +STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default); +#endif + +#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) +STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) +{ + return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); +} +#endif + +static FILE *stbi__fopen(char const *filename, char const *mode) +{ + FILE *f; +#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) + wchar_t wMode[64]; + wchar_t wFilename[1024]; + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename))) + return 0; + + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode))) + return 0; + +#if _MSC_VER >= 1400 + if (0 != _wfopen_s(&f, wFilename, wMode)) + f = 0; +#else + f = _wfopen(wFilename, wMode); +#endif + +#elif defined(_MSC_VER) && _MSC_VER >= 1400 + if (0 != fopen_s(&f, filename, mode)) + f=0; +#else + f = fopen(filename, mode); +#endif + return f; +} + + +STBIDEF stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + unsigned char *result; + if (!f) return stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *result; + stbi__context s; + stbi__start_file(&s,f); + result = stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); + if (result) { + // need to 'unget' all the characters in the IO buffer + fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); + } + return result; +} + +STBIDEF stbi__uint16 *stbi_load_from_file_16(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi__uint16 *result; + stbi__context s; + stbi__start_file(&s,f); + result = stbi__load_and_postprocess_16bit(&s,x,y,comp,req_comp); + if (result) { + // need to 'unget' all the characters in the IO buffer + fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR); + } + return result; +} + +STBIDEF stbi_us *stbi_load_16(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + stbi__uint16 *result; + if (!f) return (stbi_us *) stbi__errpuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file_16(f,x,y,comp,req_comp); + fclose(f); + return result; +} + + +#endif //!STBI_NO_STDIO + +STBIDEF stbi_us *stbi_load_16_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *channels_in_file, int desired_channels) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); +} + +STBIDEF stbi_us *stbi_load_16_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *channels_in_file, int desired_channels) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *)clbk, user); + return stbi__load_and_postprocess_16bit(&s,x,y,channels_in_file,desired_channels); +} + +STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); +} + +STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__load_and_postprocess_8bit(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_GIF +STBIDEF stbi_uc *stbi_load_gif_from_memory(stbi_uc const *buffer, int len, int **delays, int *x, int *y, int *z, int *comp, int req_comp) +{ + unsigned char *result; + stbi__context s; + stbi__start_mem(&s,buffer,len); + + result = (unsigned char*) stbi__load_gif_main(&s, delays, x, y, z, comp, req_comp); + if (stbi__vertically_flip_on_load) { + stbi__vertical_flip_slices( result, *x, *y, *z, *comp ); + } + + return result; +} +#endif + +#ifndef STBI_NO_LINEAR +static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp) +{ + unsigned char *data; + #ifndef STBI_NO_HDR + if (stbi__hdr_test(s)) { + stbi__result_info ri; + float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp, &ri); + if (hdr_data) + stbi__float_postprocess(hdr_data,x,y,comp,req_comp); + return hdr_data; + } + #endif + data = stbi__load_and_postprocess_8bit(s, x, y, comp, req_comp); + if (data) + return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); + return stbi__errpf("unknown image type", "Image not of any known type, or corrupt"); +} + +STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} + +STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} + +#ifndef STBI_NO_STDIO +STBIDEF float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) +{ + float *result; + FILE *f = stbi__fopen(filename, "rb"); + if (!f) return stbi__errpf("can't fopen", "Unable to open file"); + result = stbi_loadf_from_file(f,x,y,comp,req_comp); + fclose(f); + return result; +} + +STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) +{ + stbi__context s; + stbi__start_file(&s,f); + return stbi__loadf_main(&s,x,y,comp,req_comp); +} +#endif // !STBI_NO_STDIO + +#endif // !STBI_NO_LINEAR + +// these is-hdr-or-not is defined independent of whether STBI_NO_LINEAR is +// defined, for API simplicity; if STBI_NO_LINEAR is defined, it always +// reports false! + +STBIDEF int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(buffer); + STBI_NOTUSED(len); + return 0; + #endif +} + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_is_hdr (char const *filename) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result=0; + if (f) { + result = stbi_is_hdr_from_file(f); + fclose(f); + } + return result; +} + +STBIDEF int stbi_is_hdr_from_file(FILE *f) +{ + #ifndef STBI_NO_HDR + long pos = ftell(f); + int res; + stbi__context s; + stbi__start_file(&s,f); + res = stbi__hdr_test(&s); + fseek(f, pos, SEEK_SET); + return res; + #else + STBI_NOTUSED(f); + return 0; + #endif +} +#endif // !STBI_NO_STDIO + +STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) +{ + #ifndef STBI_NO_HDR + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user); + return stbi__hdr_test(&s); + #else + STBI_NOTUSED(clbk); + STBI_NOTUSED(user); + return 0; + #endif +} + +#ifndef STBI_NO_LINEAR +static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f; + +STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; } +STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; } +#endif + +static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f; + +STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; } +STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; } + + +////////////////////////////////////////////////////////////////////////////// +// +// Common code used by all image loaders +// + +enum +{ + STBI__SCAN_load=0, + STBI__SCAN_type, + STBI__SCAN_header +}; + +static void stbi__refill_buffer(stbi__context *s) +{ + int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); + if (n == 0) { + // at end of file, treat same as if from memory, but need to handle case + // where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file + s->read_from_callbacks = 0; + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start+1; + *s->img_buffer = 0; + } else { + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start + n; + } +} + +stbi_inline static stbi_uc stbi__get8(stbi__context *s) +{ + if (s->img_buffer < s->img_buffer_end) + return *s->img_buffer++; + if (s->read_from_callbacks) { + stbi__refill_buffer(s); + return *s->img_buffer++; + } + return 0; +} + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_HDR) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) +// nothing +#else +stbi_inline static int stbi__at_eof(stbi__context *s) +{ + if (s->io.read) { + if (!(s->io.eof)(s->io_user_data)) return 0; + // if feof() is true, check if buffer = end + // special case: we've only got the special 0 character at the end + if (s->read_from_callbacks == 0) return 1; + } + + return s->img_buffer >= s->img_buffer_end; +} +#endif + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) +// nothing +#else +static void stbi__skip(stbi__context *s, int n) +{ + if (n < 0) { + s->img_buffer = s->img_buffer_end; + return; + } + if (s->io.read) { + int blen = (int) (s->img_buffer_end - s->img_buffer); + if (blen < n) { + s->img_buffer = s->img_buffer_end; + (s->io.skip)(s->io_user_data, n - blen); + return; + } + } + s->img_buffer += n; +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_TGA) && defined(STBI_NO_HDR) && defined(STBI_NO_PNM) +// nothing +#else +static int stbi__getn(stbi__context *s, stbi_uc *buffer, int n) +{ + if (s->io.read) { + int blen = (int) (s->img_buffer_end - s->img_buffer); + if (blen < n) { + int res, count; + + memcpy(buffer, s->img_buffer, blen); + + count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); + res = (count == (n-blen)); + s->img_buffer = s->img_buffer_end; + return res; + } + } + + if (s->img_buffer+n <= s->img_buffer_end) { + memcpy(buffer, s->img_buffer, n); + s->img_buffer += n; + return 1; + } else + return 0; +} +#endif + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) +// nothing +#else +static int stbi__get16be(stbi__context *s) +{ + int z = stbi__get8(s); + return (z << 8) + stbi__get8(s); +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) && defined(STBI_NO_PIC) +// nothing +#else +static stbi__uint32 stbi__get32be(stbi__context *s) +{ + stbi__uint32 z = stbi__get16be(s); + return (z << 16) + stbi__get16be(s); +} +#endif + +#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) +// nothing +#else +static int stbi__get16le(stbi__context *s) +{ + int z = stbi__get8(s); + return z + (stbi__get8(s) << 8); +} +#endif + +#ifndef STBI_NO_BMP +static stbi__uint32 stbi__get32le(stbi__context *s) +{ + stbi__uint32 z = stbi__get16le(s); + return z + (stbi__get16le(s) << 16); +} +#endif + +#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings + +#if defined(STBI_NO_JPEG) && defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) +// nothing +#else +////////////////////////////////////////////////////////////////////////////// +// +// generic converter from built-in img_n to req_comp +// individual types do this automatically as much as possible (e.g. jpeg +// does all cases internally since it needs to colorspace convert anyway, +// and it never has alpha, so very few cases ). png can automatically +// interleave an alpha=255 channel, but falls back to this for other cases +// +// assume data buffer is malloced, so malloc a new one and free that one +// only failure mode is malloc failing + +static stbi_uc stbi__compute_y(int r, int g, int b) +{ + return (stbi_uc) (((r*77) + (g*150) + (29*b)) >> 8); +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_BMP) && defined(STBI_NO_PSD) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF) && defined(STBI_NO_PIC) && defined(STBI_NO_PNM) +// nothing +#else +static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int req_comp, unsigned int x, unsigned int y) +{ + int i,j; + unsigned char *good; + + if (req_comp == img_n) return data; + STBI_ASSERT(req_comp >= 1 && req_comp <= 4); + + good = (unsigned char *) stbi__malloc_mad3(req_comp, x, y, 0); + if (good == NULL) { + STBI_FREE(data); + return stbi__errpuc("outofmem", "Out of memory"); + } + + for (j=0; j < (int) y; ++j) { + unsigned char *src = data + j * x * img_n ; + unsigned char *dest = good + j * x * req_comp; + + #define STBI__COMBO(a,b) ((a)*8+(b)) + #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (STBI__COMBO(img_n, req_comp)) { + STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=255; } break; + STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=255; } break; + STBI__CASE(2,1) { dest[0]=src[0]; } break; + STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break; + STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=255; } break; + STBI__CASE(3,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; + STBI__CASE(3,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = 255; } break; + STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break; + STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break; + STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break; + default: STBI_ASSERT(0); + } + #undef STBI__CASE + } + + STBI_FREE(data); + return good; +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) +// nothing +#else +static stbi__uint16 stbi__compute_y_16(int r, int g, int b) +{ + return (stbi__uint16) (((r*77) + (g*150) + (29*b)) >> 8); +} +#endif + +#if defined(STBI_NO_PNG) && defined(STBI_NO_PSD) +// nothing +#else +static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int req_comp, unsigned int x, unsigned int y) +{ + int i,j; + stbi__uint16 *good; + + if (req_comp == img_n) return data; + STBI_ASSERT(req_comp >= 1 && req_comp <= 4); + + good = (stbi__uint16 *) stbi__malloc(req_comp * x * y * 2); + if (good == NULL) { + STBI_FREE(data); + return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); + } + + for (j=0; j < (int) y; ++j) { + stbi__uint16 *src = data + j * x * img_n ; + stbi__uint16 *dest = good + j * x * req_comp; + + #define STBI__COMBO(a,b) ((a)*8+(b)) + #define STBI__CASE(a,b) case STBI__COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (STBI__COMBO(img_n, req_comp)) { + STBI__CASE(1,2) { dest[0]=src[0]; dest[1]=0xffff; } break; + STBI__CASE(1,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(1,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=0xffff; } break; + STBI__CASE(2,1) { dest[0]=src[0]; } break; + STBI__CASE(2,3) { dest[0]=dest[1]=dest[2]=src[0]; } break; + STBI__CASE(2,4) { dest[0]=dest[1]=dest[2]=src[0]; dest[3]=src[1]; } break; + STBI__CASE(3,4) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2];dest[3]=0xffff; } break; + STBI__CASE(3,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; + STBI__CASE(3,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = 0xffff; } break; + STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break; + STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break; + STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break; + default: STBI_ASSERT(0); + } + #undef STBI__CASE + } + + STBI_FREE(data); + return good; +} +#endif + +#ifndef STBI_NO_LINEAR +static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp) +{ + int i,k,n; + float *output; + if (!data) return NULL; + output = (float *) stbi__malloc_mad4(x, y, comp, sizeof(float), 0); + if (output == NULL) { STBI_FREE(data); return stbi__errpf("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + output[i*comp + k] = (float) (pow(data[i*comp+k]/255.0f, stbi__l2h_gamma) * stbi__l2h_scale); + } + } + if (n < comp) { + for (i=0; i < x*y; ++i) { + output[i*comp + n] = data[i*comp + n]/255.0f; + } + } + STBI_FREE(data); + return output; +} +#endif + +#ifndef STBI_NO_HDR +#define stbi__float2int(x) ((int) (x)) +static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp) +{ + int i,k,n; + stbi_uc *output; + if (!data) return NULL; + output = (stbi_uc *) stbi__malloc_mad3(x, y, comp, 0); + if (output == NULL) { STBI_FREE(data); return stbi__errpuc("outofmem", "Out of memory"); } + // compute number of non-alpha components + if (comp & 1) n = comp; else n = comp-1; + for (i=0; i < x*y; ++i) { + for (k=0; k < n; ++k) { + float z = (float) pow(data[i*comp+k]*stbi__h2l_scale_i, stbi__h2l_gamma_i) * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (stbi_uc) stbi__float2int(z); + } + if (k < comp) { + float z = data[i*comp+k] * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i*comp + k] = (stbi_uc) stbi__float2int(z); + } + } + STBI_FREE(data); + return output; +} +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// "baseline" JPEG/JFIF decoder +// +// simple implementation +// - doesn't support delayed output of y-dimension +// - simple interface (only one output format: 8-bit interleaved RGB) +// - doesn't try to recover corrupt jpegs +// - doesn't allow partial loading, loading multiple at once +// - still fast on x86 (copying globals into locals doesn't help x86) +// - allocates lots of intermediate memory (full size of all components) +// - non-interleaved case requires this anyway +// - allows good upsampling (see next) +// high-quality +// - upsampled channels are bilinearly interpolated, even across blocks +// - quality integer IDCT derived from IJG's 'slow' +// performance +// - fast huffman; reasonable integer IDCT +// - some SIMD kernels for common paths on targets with SSE2/NEON +// - uses a lot of intermediate memory, could cache poorly + +#ifndef STBI_NO_JPEG + +// huffman decoding acceleration +#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache + +typedef struct +{ + stbi_uc fast[1 << FAST_BITS]; + // weirdly, repacking this into AoS is a 10% speed loss, instead of a win + stbi__uint16 code[256]; + stbi_uc values[256]; + stbi_uc size[257]; + unsigned int maxcode[18]; + int delta[17]; // old 'firstsymbol' - old 'firstcode' +} stbi__huffman; + +typedef struct +{ + stbi__context *s; + stbi__huffman huff_dc[4]; + stbi__huffman huff_ac[4]; + stbi__uint16 dequant[4][64]; + stbi__int16 fast_ac[4][1 << FAST_BITS]; + +// sizes for components, interleaved MCUs + int img_h_max, img_v_max; + int img_mcu_x, img_mcu_y; + int img_mcu_w, img_mcu_h; + +// definition of jpeg image component + struct + { + int id; + int h,v; + int tq; + int hd,ha; + int dc_pred; + + int x,y,w2,h2; + stbi_uc *data; + void *raw_data, *raw_coeff; + stbi_uc *linebuf; + short *coeff; // progressive only + int coeff_w, coeff_h; // number of 8x8 coefficient blocks + } img_comp[4]; + + stbi__uint32 code_buffer; // jpeg entropy-coded buffer + int code_bits; // number of valid bits + unsigned char marker; // marker seen while filling entropy buffer + int nomore; // flag if we saw a marker so must stop + + int progressive; + int spec_start; + int spec_end; + int succ_high; + int succ_low; + int eob_run; + int jfif; + int app14_color_transform; // Adobe APP14 tag + int rgb; + + int scan_n, order[4]; + int restart_interval, todo; + +// kernels + void (*idct_block_kernel)(stbi_uc *out, int out_stride, short data[64]); + void (*YCbCr_to_RGB_kernel)(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step); + stbi_uc *(*resample_row_hv_2_kernel)(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs); +} stbi__jpeg; + +static int stbi__build_huffman(stbi__huffman *h, int *count) +{ + int i,j,k=0; + unsigned int code; + // build size list for each symbol (from JPEG spec) + for (i=0; i < 16; ++i) + for (j=0; j < count[i]; ++j) + h->size[k++] = (stbi_uc) (i+1); + h->size[k] = 0; + + // compute actual symbols (from jpeg spec) + code = 0; + k = 0; + for(j=1; j <= 16; ++j) { + // compute delta to add to code to compute symbol id + h->delta[j] = k - code; + if (h->size[k] == j) { + while (h->size[k] == j) + h->code[k++] = (stbi__uint16) (code++); + if (code-1 >= (1u << j)) return stbi__err("bad code lengths","Corrupt JPEG"); + } + // compute largest code + 1 for this size, preshifted as needed later + h->maxcode[j] = code << (16-j); + code <<= 1; + } + h->maxcode[j] = 0xffffffff; + + // build non-spec acceleration table; 255 is flag for not-accelerated + memset(h->fast, 255, 1 << FAST_BITS); + for (i=0; i < k; ++i) { + int s = h->size[i]; + if (s <= FAST_BITS) { + int c = h->code[i] << (FAST_BITS-s); + int m = 1 << (FAST_BITS-s); + for (j=0; j < m; ++j) { + h->fast[c+j] = (stbi_uc) i; + } + } + } + return 1; +} + +// build a table that decodes both magnitude and value of small ACs in +// one go. +static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h) +{ + int i; + for (i=0; i < (1 << FAST_BITS); ++i) { + stbi_uc fast = h->fast[i]; + fast_ac[i] = 0; + if (fast < 255) { + int rs = h->values[fast]; + int run = (rs >> 4) & 15; + int magbits = rs & 15; + int len = h->size[fast]; + + if (magbits && len + magbits <= FAST_BITS) { + // magnitude code followed by receive_extend code + int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits); + int m = 1 << (magbits - 1); + if (k < m) k += (~0U << magbits) + 1; + // if the result is small enough, we can fit it in fast_ac table + if (k >= -128 && k <= 127) + fast_ac[i] = (stbi__int16) ((k * 256) + (run * 16) + (len + magbits)); + } + } + } +} + +static void stbi__grow_buffer_unsafe(stbi__jpeg *j) +{ + do { + unsigned int b = j->nomore ? 0 : stbi__get8(j->s); + if (b == 0xff) { + int c = stbi__get8(j->s); + while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes + if (c != 0) { + j->marker = (unsigned char) c; + j->nomore = 1; + return; + } + } + j->code_buffer |= b << (24 - j->code_bits); + j->code_bits += 8; + } while (j->code_bits <= 24); +} + +// (1 << n) - 1 +static const stbi__uint32 stbi__bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; + +// decode a jpeg huffman value from the bitstream +stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h) +{ + unsigned int temp; + int c,k; + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + + // look at the top FAST_BITS and determine what symbol ID it is, + // if the code is <= FAST_BITS + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + k = h->fast[c]; + if (k < 255) { + int s = h->size[k]; + if (s > j->code_bits) + return -1; + j->code_buffer <<= s; + j->code_bits -= s; + return h->values[k]; + } + + // naive test is to shift the code_buffer down so k bits are + // valid, then test against maxcode. To speed this up, we've + // preshifted maxcode left so that it has (16-k) 0s at the + // end; in other words, regardless of the number of bits, it + // wants to be compared against something shifted to have 16; + // that way we don't need to shift inside the loop. + temp = j->code_buffer >> 16; + for (k=FAST_BITS+1 ; ; ++k) + if (temp < h->maxcode[k]) + break; + if (k == 17) { + // error! code not found + j->code_bits -= 16; + return -1; + } + + if (k > j->code_bits) + return -1; + + // convert the huffman code to the symbol id + c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k]; + STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]); + + // convert the id to a symbol + j->code_bits -= k; + j->code_buffer <<= k; + return h->values[c]; +} + +// bias[n] = (-1<code_bits < n) stbi__grow_buffer_unsafe(j); + + sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB + k = stbi_lrot(j->code_buffer, n); + STBI_ASSERT(n >= 0 && n < (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask))); + j->code_buffer = k & ~stbi__bmask[n]; + k &= stbi__bmask[n]; + j->code_bits -= n; + return k + (stbi__jbias[n] & ~sgn); +} + +// get some unsigned bits +stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n) +{ + unsigned int k; + if (j->code_bits < n) stbi__grow_buffer_unsafe(j); + k = stbi_lrot(j->code_buffer, n); + j->code_buffer = k & ~stbi__bmask[n]; + k &= stbi__bmask[n]; + j->code_bits -= n; + return k; +} + +stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j) +{ + unsigned int k; + if (j->code_bits < 1) stbi__grow_buffer_unsafe(j); + k = j->code_buffer; + j->code_buffer <<= 1; + --j->code_bits; + return k & 0x80000000; +} + +// given a value that's at position X in the zigzag stream, +// where does it appear in the 8x8 matrix coded as row-major? +static const stbi_uc stbi__jpeg_dezigzag[64+15] = +{ + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + // let corrupt input sample past end + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63 +}; + +// decode one 64-entry block-- +static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi__uint16 *dequant) +{ + int diff,dc,k; + int t; + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + t = stbi__jpeg_huff_decode(j, hdc); + if (t < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + + // 0 all the ac values now so we can do it 32-bits at a time + memset(data,0,64*sizeof(data[0])); + + diff = t ? stbi__extend_receive(j, t) : 0; + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) (dc * dequant[0]); + + // decode AC components, see JPEG spec + k = 1; + do { + unsigned int zig; + int c,r,s; + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + r = fac[c]; + if (r) { // fast-AC path + k += (r >> 4) & 15; // run + s = r & 15; // combined length + j->code_buffer <<= s; + j->code_bits -= s; + // decode into unzigzag'd location + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) ((r >> 8) * dequant[zig]); + } else { + int rs = stbi__jpeg_huff_decode(j, hac); + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (rs != 0xf0) break; // end block + k += 16; + } else { + k += r; + // decode into unzigzag'd location + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) (stbi__extend_receive(j,s) * dequant[zig]); + } + } + } while (k < 64); + return 1; +} + +static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__huffman *hdc, int b) +{ + int diff,dc; + int t; + if (j->spec_end != 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + + if (j->succ_high == 0) { + // first scan for DC coefficient, must be first + memset(data,0,64*sizeof(data[0])); // 0 all the ac values now + t = stbi__jpeg_huff_decode(j, hdc); + diff = t ? stbi__extend_receive(j, t) : 0; + + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short) (dc << j->succ_low); + } else { + // refinement scan for DC coefficient + if (stbi__jpeg_get_bit(j)) + data[0] += (short) (1 << j->succ_low); + } + return 1; +} + +// @OPTIMIZE: store non-zigzagged during the decode passes, +// and only de-zigzag when dequantizing +static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__huffman *hac, stbi__int16 *fac) +{ + int k; + if (j->spec_start == 0) return stbi__err("can't merge dc and ac", "Corrupt JPEG"); + + if (j->succ_high == 0) { + int shift = j->succ_low; + + if (j->eob_run) { + --j->eob_run; + return 1; + } + + k = j->spec_start; + do { + unsigned int zig; + int c,r,s; + if (j->code_bits < 16) stbi__grow_buffer_unsafe(j); + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); + r = fac[c]; + if (r) { // fast-AC path + k += (r >> 4) & 15; // run + s = r & 15; // combined length + j->code_buffer <<= s; + j->code_bits -= s; + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) ((r >> 8) << shift); + } else { + int rs = stbi__jpeg_huff_decode(j, hac); + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (r < 15) { + j->eob_run = (1 << r); + if (r) + j->eob_run += stbi__jpeg_get_bits(j, r); + --j->eob_run; + break; + } + k += 16; + } else { + k += r; + zig = stbi__jpeg_dezigzag[k++]; + data[zig] = (short) (stbi__extend_receive(j,s) << shift); + } + } + } while (k <= j->spec_end); + } else { + // refinement scan for these AC coefficients + + short bit = (short) (1 << j->succ_low); + + if (j->eob_run) { + --j->eob_run; + for (k = j->spec_start; k <= j->spec_end; ++k) { + short *p = &data[stbi__jpeg_dezigzag[k]]; + if (*p != 0) + if (stbi__jpeg_get_bit(j)) + if ((*p & bit)==0) { + if (*p > 0) + *p += bit; + else + *p -= bit; + } + } + } else { + k = j->spec_start; + do { + int r,s; + int rs = stbi__jpeg_huff_decode(j, hac); // @OPTIMIZE see if we can use the fast path here, advance-by-r is so slow, eh + if (rs < 0) return stbi__err("bad huffman code","Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) { + if (r < 15) { + j->eob_run = (1 << r) - 1; + if (r) + j->eob_run += stbi__jpeg_get_bits(j, r); + r = 64; // force end of block + } else { + // r=15 s=0 should write 16 0s, so we just do + // a run of 15 0s and then write s (which is 0), + // so we don't have to do anything special here + } + } else { + if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG"); + // sign bit + if (stbi__jpeg_get_bit(j)) + s = bit; + else + s = -bit; + } + + // advance by r + while (k <= j->spec_end) { + short *p = &data[stbi__jpeg_dezigzag[k++]]; + if (*p != 0) { + if (stbi__jpeg_get_bit(j)) + if ((*p & bit)==0) { + if (*p > 0) + *p += bit; + else + *p -= bit; + } + } else { + if (r == 0) { + *p = (short) s; + break; + } + --r; + } + } + } while (k <= j->spec_end); + } + } + return 1; +} + +// take a -128..127 value and stbi__clamp it and convert to 0..255 +stbi_inline static stbi_uc stbi__clamp(int x) +{ + // trick to use a single test to catch both cases + if ((unsigned int) x > 255) { + if (x < 0) return 0; + if (x > 255) return 255; + } + return (stbi_uc) x; +} + +#define stbi__f2f(x) ((int) (((x) * 4096 + 0.5))) +#define stbi__fsh(x) ((x) * 4096) + +// derived from jidctint -- DCT_ISLOW +#define STBI__IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ + int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ + p2 = s2; \ + p3 = s6; \ + p1 = (p2+p3) * stbi__f2f(0.5411961f); \ + t2 = p1 + p3*stbi__f2f(-1.847759065f); \ + t3 = p1 + p2*stbi__f2f( 0.765366865f); \ + p2 = s0; \ + p3 = s4; \ + t0 = stbi__fsh(p2+p3); \ + t1 = stbi__fsh(p2-p3); \ + x0 = t0+t3; \ + x3 = t0-t3; \ + x1 = t1+t2; \ + x2 = t1-t2; \ + t0 = s7; \ + t1 = s5; \ + t2 = s3; \ + t3 = s1; \ + p3 = t0+t2; \ + p4 = t1+t3; \ + p1 = t0+t3; \ + p2 = t1+t2; \ + p5 = (p3+p4)*stbi__f2f( 1.175875602f); \ + t0 = t0*stbi__f2f( 0.298631336f); \ + t1 = t1*stbi__f2f( 2.053119869f); \ + t2 = t2*stbi__f2f( 3.072711026f); \ + t3 = t3*stbi__f2f( 1.501321110f); \ + p1 = p5 + p1*stbi__f2f(-0.899976223f); \ + p2 = p5 + p2*stbi__f2f(-2.562915447f); \ + p3 = p3*stbi__f2f(-1.961570560f); \ + p4 = p4*stbi__f2f(-0.390180644f); \ + t3 += p1+p4; \ + t2 += p2+p3; \ + t1 += p2+p4; \ + t0 += p1+p3; + +static void stbi__idct_block(stbi_uc *out, int out_stride, short data[64]) +{ + int i,val[64],*v=val; + stbi_uc *o; + short *d = data; + + // columns + for (i=0; i < 8; ++i,++d, ++v) { + // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing + if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 + && d[40]==0 && d[48]==0 && d[56]==0) { + // no shortcut 0 seconds + // (1|2|3|4|5|6|7)==0 0 seconds + // all separate -0.047 seconds + // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds + int dcterm = d[0]*4; + v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; + } else { + STBI__IDCT_1D(d[ 0],d[ 8],d[16],d[24],d[32],d[40],d[48],d[56]) + // constants scaled things up by 1<<12; let's bring them back + // down, but keep 2 extra bits of precision + x0 += 512; x1 += 512; x2 += 512; x3 += 512; + v[ 0] = (x0+t3) >> 10; + v[56] = (x0-t3) >> 10; + v[ 8] = (x1+t2) >> 10; + v[48] = (x1-t2) >> 10; + v[16] = (x2+t1) >> 10; + v[40] = (x2-t1) >> 10; + v[24] = (x3+t0) >> 10; + v[32] = (x3-t0) >> 10; + } + } + + for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { + // no fast case since the first 1D IDCT spread components out + STBI__IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) + // constants scaled things up by 1<<12, plus we had 1<<2 from first + // loop, plus horizontal and vertical each scale by sqrt(8) so together + // we've got an extra 1<<3, so 1<<17 total we need to remove. + // so we want to round that, which means adding 0.5 * 1<<17, + // aka 65536. Also, we'll end up with -128 to 127 that we want + // to encode as 0..255 by adding 128, so we'll add that before the shift + x0 += 65536 + (128<<17); + x1 += 65536 + (128<<17); + x2 += 65536 + (128<<17); + x3 += 65536 + (128<<17); + // tried computing the shifts into temps, or'ing the temps to see + // if any were out of range, but that was slower + o[0] = stbi__clamp((x0+t3) >> 17); + o[7] = stbi__clamp((x0-t3) >> 17); + o[1] = stbi__clamp((x1+t2) >> 17); + o[6] = stbi__clamp((x1-t2) >> 17); + o[2] = stbi__clamp((x2+t1) >> 17); + o[5] = stbi__clamp((x2-t1) >> 17); + o[3] = stbi__clamp((x3+t0) >> 17); + o[4] = stbi__clamp((x3-t0) >> 17); + } +} + +#ifdef STBI_SSE2 +// sse2 integer IDCT. not the fastest possible implementation but it +// produces bit-identical results to the generic C version so it's +// fully "transparent". +static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) +{ + // This is constructed to match our regular (generic) integer IDCT exactly. + __m128i row0, row1, row2, row3, row4, row5, row6, row7; + __m128i tmp; + + // dot product constant: even elems=x, odd elems=y + #define dct_const(x,y) _mm_setr_epi16((x),(y),(x),(y),(x),(y),(x),(y)) + + // out(0) = c0[even]*x + c0[odd]*y (c0, x, y 16-bit, out 32-bit) + // out(1) = c1[even]*x + c1[odd]*y + #define dct_rot(out0,out1, x,y,c0,c1) \ + __m128i c0##lo = _mm_unpacklo_epi16((x),(y)); \ + __m128i c0##hi = _mm_unpackhi_epi16((x),(y)); \ + __m128i out0##_l = _mm_madd_epi16(c0##lo, c0); \ + __m128i out0##_h = _mm_madd_epi16(c0##hi, c0); \ + __m128i out1##_l = _mm_madd_epi16(c0##lo, c1); \ + __m128i out1##_h = _mm_madd_epi16(c0##hi, c1) + + // out = in << 12 (in 16-bit, out 32-bit) + #define dct_widen(out, in) \ + __m128i out##_l = _mm_srai_epi32(_mm_unpacklo_epi16(_mm_setzero_si128(), (in)), 4); \ + __m128i out##_h = _mm_srai_epi32(_mm_unpackhi_epi16(_mm_setzero_si128(), (in)), 4) + + // wide add + #define dct_wadd(out, a, b) \ + __m128i out##_l = _mm_add_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_add_epi32(a##_h, b##_h) + + // wide sub + #define dct_wsub(out, a, b) \ + __m128i out##_l = _mm_sub_epi32(a##_l, b##_l); \ + __m128i out##_h = _mm_sub_epi32(a##_h, b##_h) + + // butterfly a/b, add bias, then shift by "s" and pack + #define dct_bfly32o(out0, out1, a,b,bias,s) \ + { \ + __m128i abiased_l = _mm_add_epi32(a##_l, bias); \ + __m128i abiased_h = _mm_add_epi32(a##_h, bias); \ + dct_wadd(sum, abiased, b); \ + dct_wsub(dif, abiased, b); \ + out0 = _mm_packs_epi32(_mm_srai_epi32(sum_l, s), _mm_srai_epi32(sum_h, s)); \ + out1 = _mm_packs_epi32(_mm_srai_epi32(dif_l, s), _mm_srai_epi32(dif_h, s)); \ + } + + // 8-bit interleave step (for transposes) + #define dct_interleave8(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi8(a, b); \ + b = _mm_unpackhi_epi8(tmp, b) + + // 16-bit interleave step (for transposes) + #define dct_interleave16(a, b) \ + tmp = a; \ + a = _mm_unpacklo_epi16(a, b); \ + b = _mm_unpackhi_epi16(tmp, b) + + #define dct_pass(bias,shift) \ + { \ + /* even part */ \ + dct_rot(t2e,t3e, row2,row6, rot0_0,rot0_1); \ + __m128i sum04 = _mm_add_epi16(row0, row4); \ + __m128i dif04 = _mm_sub_epi16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + dct_rot(y0o,y2o, row7,row3, rot2_0,rot2_1); \ + dct_rot(y1o,y3o, row5,row1, rot3_0,rot3_1); \ + __m128i sum17 = _mm_add_epi16(row1, row7); \ + __m128i sum35 = _mm_add_epi16(row3, row5); \ + dct_rot(y4o,y5o, sum17,sum35, rot1_0,rot1_1); \ + dct_wadd(x4, y0o, y4o); \ + dct_wadd(x5, y1o, y5o); \ + dct_wadd(x6, y2o, y5o); \ + dct_wadd(x7, y3o, y4o); \ + dct_bfly32o(row0,row7, x0,x7,bias,shift); \ + dct_bfly32o(row1,row6, x1,x6,bias,shift); \ + dct_bfly32o(row2,row5, x2,x5,bias,shift); \ + dct_bfly32o(row3,row4, x3,x4,bias,shift); \ + } + + __m128i rot0_0 = dct_const(stbi__f2f(0.5411961f), stbi__f2f(0.5411961f) + stbi__f2f(-1.847759065f)); + __m128i rot0_1 = dct_const(stbi__f2f(0.5411961f) + stbi__f2f( 0.765366865f), stbi__f2f(0.5411961f)); + __m128i rot1_0 = dct_const(stbi__f2f(1.175875602f) + stbi__f2f(-0.899976223f), stbi__f2f(1.175875602f)); + __m128i rot1_1 = dct_const(stbi__f2f(1.175875602f), stbi__f2f(1.175875602f) + stbi__f2f(-2.562915447f)); + __m128i rot2_0 = dct_const(stbi__f2f(-1.961570560f) + stbi__f2f( 0.298631336f), stbi__f2f(-1.961570560f)); + __m128i rot2_1 = dct_const(stbi__f2f(-1.961570560f), stbi__f2f(-1.961570560f) + stbi__f2f( 3.072711026f)); + __m128i rot3_0 = dct_const(stbi__f2f(-0.390180644f) + stbi__f2f( 2.053119869f), stbi__f2f(-0.390180644f)); + __m128i rot3_1 = dct_const(stbi__f2f(-0.390180644f), stbi__f2f(-0.390180644f) + stbi__f2f( 1.501321110f)); + + // rounding biases in column/row passes, see stbi__idct_block for explanation. + __m128i bias_0 = _mm_set1_epi32(512); + __m128i bias_1 = _mm_set1_epi32(65536 + (128<<17)); + + // load + row0 = _mm_load_si128((const __m128i *) (data + 0*8)); + row1 = _mm_load_si128((const __m128i *) (data + 1*8)); + row2 = _mm_load_si128((const __m128i *) (data + 2*8)); + row3 = _mm_load_si128((const __m128i *) (data + 3*8)); + row4 = _mm_load_si128((const __m128i *) (data + 4*8)); + row5 = _mm_load_si128((const __m128i *) (data + 5*8)); + row6 = _mm_load_si128((const __m128i *) (data + 6*8)); + row7 = _mm_load_si128((const __m128i *) (data + 7*8)); + + // column pass + dct_pass(bias_0, 10); + + { + // 16bit 8x8 transpose pass 1 + dct_interleave16(row0, row4); + dct_interleave16(row1, row5); + dct_interleave16(row2, row6); + dct_interleave16(row3, row7); + + // transpose pass 2 + dct_interleave16(row0, row2); + dct_interleave16(row1, row3); + dct_interleave16(row4, row6); + dct_interleave16(row5, row7); + + // transpose pass 3 + dct_interleave16(row0, row1); + dct_interleave16(row2, row3); + dct_interleave16(row4, row5); + dct_interleave16(row6, row7); + } + + // row pass + dct_pass(bias_1, 17); + + { + // pack + __m128i p0 = _mm_packus_epi16(row0, row1); // a0a1a2a3...a7b0b1b2b3...b7 + __m128i p1 = _mm_packus_epi16(row2, row3); + __m128i p2 = _mm_packus_epi16(row4, row5); + __m128i p3 = _mm_packus_epi16(row6, row7); + + // 8bit 8x8 transpose pass 1 + dct_interleave8(p0, p2); // a0e0a1e1... + dct_interleave8(p1, p3); // c0g0c1g1... + + // transpose pass 2 + dct_interleave8(p0, p1); // a0c0e0g0... + dct_interleave8(p2, p3); // b0d0f0h0... + + // transpose pass 3 + dct_interleave8(p0, p2); // a0b0c0d0... + dct_interleave8(p1, p3); // a4b4c4d4... + + // store + _mm_storel_epi64((__m128i *) out, p0); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p0, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p2); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p2, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p1); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p1, 0x4e)); out += out_stride; + _mm_storel_epi64((__m128i *) out, p3); out += out_stride; + _mm_storel_epi64((__m128i *) out, _mm_shuffle_epi32(p3, 0x4e)); + } + +#undef dct_const +#undef dct_rot +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_interleave8 +#undef dct_interleave16 +#undef dct_pass +} + +#endif // STBI_SSE2 + +#ifdef STBI_NEON + +// NEON integer IDCT. should produce bit-identical +// results to the generic C version. +static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64]) +{ + int16x8_t row0, row1, row2, row3, row4, row5, row6, row7; + + int16x4_t rot0_0 = vdup_n_s16(stbi__f2f(0.5411961f)); + int16x4_t rot0_1 = vdup_n_s16(stbi__f2f(-1.847759065f)); + int16x4_t rot0_2 = vdup_n_s16(stbi__f2f( 0.765366865f)); + int16x4_t rot1_0 = vdup_n_s16(stbi__f2f( 1.175875602f)); + int16x4_t rot1_1 = vdup_n_s16(stbi__f2f(-0.899976223f)); + int16x4_t rot1_2 = vdup_n_s16(stbi__f2f(-2.562915447f)); + int16x4_t rot2_0 = vdup_n_s16(stbi__f2f(-1.961570560f)); + int16x4_t rot2_1 = vdup_n_s16(stbi__f2f(-0.390180644f)); + int16x4_t rot3_0 = vdup_n_s16(stbi__f2f( 0.298631336f)); + int16x4_t rot3_1 = vdup_n_s16(stbi__f2f( 2.053119869f)); + int16x4_t rot3_2 = vdup_n_s16(stbi__f2f( 3.072711026f)); + int16x4_t rot3_3 = vdup_n_s16(stbi__f2f( 1.501321110f)); + +#define dct_long_mul(out, inq, coeff) \ + int32x4_t out##_l = vmull_s16(vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmull_s16(vget_high_s16(inq), coeff) + +#define dct_long_mac(out, acc, inq, coeff) \ + int32x4_t out##_l = vmlal_s16(acc##_l, vget_low_s16(inq), coeff); \ + int32x4_t out##_h = vmlal_s16(acc##_h, vget_high_s16(inq), coeff) + +#define dct_widen(out, inq) \ + int32x4_t out##_l = vshll_n_s16(vget_low_s16(inq), 12); \ + int32x4_t out##_h = vshll_n_s16(vget_high_s16(inq), 12) + +// wide add +#define dct_wadd(out, a, b) \ + int32x4_t out##_l = vaddq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vaddq_s32(a##_h, b##_h) + +// wide sub +#define dct_wsub(out, a, b) \ + int32x4_t out##_l = vsubq_s32(a##_l, b##_l); \ + int32x4_t out##_h = vsubq_s32(a##_h, b##_h) + +// butterfly a/b, then shift using "shiftop" by "s" and pack +#define dct_bfly32o(out0,out1, a,b,shiftop,s) \ + { \ + dct_wadd(sum, a, b); \ + dct_wsub(dif, a, b); \ + out0 = vcombine_s16(shiftop(sum_l, s), shiftop(sum_h, s)); \ + out1 = vcombine_s16(shiftop(dif_l, s), shiftop(dif_h, s)); \ + } + +#define dct_pass(shiftop, shift) \ + { \ + /* even part */ \ + int16x8_t sum26 = vaddq_s16(row2, row6); \ + dct_long_mul(p1e, sum26, rot0_0); \ + dct_long_mac(t2e, p1e, row6, rot0_1); \ + dct_long_mac(t3e, p1e, row2, rot0_2); \ + int16x8_t sum04 = vaddq_s16(row0, row4); \ + int16x8_t dif04 = vsubq_s16(row0, row4); \ + dct_widen(t0e, sum04); \ + dct_widen(t1e, dif04); \ + dct_wadd(x0, t0e, t3e); \ + dct_wsub(x3, t0e, t3e); \ + dct_wadd(x1, t1e, t2e); \ + dct_wsub(x2, t1e, t2e); \ + /* odd part */ \ + int16x8_t sum15 = vaddq_s16(row1, row5); \ + int16x8_t sum17 = vaddq_s16(row1, row7); \ + int16x8_t sum35 = vaddq_s16(row3, row5); \ + int16x8_t sum37 = vaddq_s16(row3, row7); \ + int16x8_t sumodd = vaddq_s16(sum17, sum35); \ + dct_long_mul(p5o, sumodd, rot1_0); \ + dct_long_mac(p1o, p5o, sum17, rot1_1); \ + dct_long_mac(p2o, p5o, sum35, rot1_2); \ + dct_long_mul(p3o, sum37, rot2_0); \ + dct_long_mul(p4o, sum15, rot2_1); \ + dct_wadd(sump13o, p1o, p3o); \ + dct_wadd(sump24o, p2o, p4o); \ + dct_wadd(sump23o, p2o, p3o); \ + dct_wadd(sump14o, p1o, p4o); \ + dct_long_mac(x4, sump13o, row7, rot3_0); \ + dct_long_mac(x5, sump24o, row5, rot3_1); \ + dct_long_mac(x6, sump23o, row3, rot3_2); \ + dct_long_mac(x7, sump14o, row1, rot3_3); \ + dct_bfly32o(row0,row7, x0,x7,shiftop,shift); \ + dct_bfly32o(row1,row6, x1,x6,shiftop,shift); \ + dct_bfly32o(row2,row5, x2,x5,shiftop,shift); \ + dct_bfly32o(row3,row4, x3,x4,shiftop,shift); \ + } + + // load + row0 = vld1q_s16(data + 0*8); + row1 = vld1q_s16(data + 1*8); + row2 = vld1q_s16(data + 2*8); + row3 = vld1q_s16(data + 3*8); + row4 = vld1q_s16(data + 4*8); + row5 = vld1q_s16(data + 5*8); + row6 = vld1q_s16(data + 6*8); + row7 = vld1q_s16(data + 7*8); + + // add DC bias + row0 = vaddq_s16(row0, vsetq_lane_s16(1024, vdupq_n_s16(0), 0)); + + // column pass + dct_pass(vrshrn_n_s32, 10); + + // 16bit 8x8 transpose + { +// these three map to a single VTRN.16, VTRN.32, and VSWP, respectively. +// whether compilers actually get this is another story, sadly. +#define dct_trn16(x, y) { int16x8x2_t t = vtrnq_s16(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn32(x, y) { int32x4x2_t t = vtrnq_s32(vreinterpretq_s32_s16(x), vreinterpretq_s32_s16(y)); x = vreinterpretq_s16_s32(t.val[0]); y = vreinterpretq_s16_s32(t.val[1]); } +#define dct_trn64(x, y) { int16x8_t x0 = x; int16x8_t y0 = y; x = vcombine_s16(vget_low_s16(x0), vget_low_s16(y0)); y = vcombine_s16(vget_high_s16(x0), vget_high_s16(y0)); } + + // pass 1 + dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6 + dct_trn16(row2, row3); + dct_trn16(row4, row5); + dct_trn16(row6, row7); + + // pass 2 + dct_trn32(row0, row2); // a0b0c0d0a4b4c4d4 + dct_trn32(row1, row3); + dct_trn32(row4, row6); + dct_trn32(row5, row7); + + // pass 3 + dct_trn64(row0, row4); // a0b0c0d0e0f0g0h0 + dct_trn64(row1, row5); + dct_trn64(row2, row6); + dct_trn64(row3, row7); + +#undef dct_trn16 +#undef dct_trn32 +#undef dct_trn64 + } + + // row pass + // vrshrn_n_s32 only supports shifts up to 16, we need + // 17. so do a non-rounding shift of 16 first then follow + // up with a rounding shift by 1. + dct_pass(vshrn_n_s32, 16); + + { + // pack and round + uint8x8_t p0 = vqrshrun_n_s16(row0, 1); + uint8x8_t p1 = vqrshrun_n_s16(row1, 1); + uint8x8_t p2 = vqrshrun_n_s16(row2, 1); + uint8x8_t p3 = vqrshrun_n_s16(row3, 1); + uint8x8_t p4 = vqrshrun_n_s16(row4, 1); + uint8x8_t p5 = vqrshrun_n_s16(row5, 1); + uint8x8_t p6 = vqrshrun_n_s16(row6, 1); + uint8x8_t p7 = vqrshrun_n_s16(row7, 1); + + // again, these can translate into one instruction, but often don't. +#define dct_trn8_8(x, y) { uint8x8x2_t t = vtrn_u8(x, y); x = t.val[0]; y = t.val[1]; } +#define dct_trn8_16(x, y) { uint16x4x2_t t = vtrn_u16(vreinterpret_u16_u8(x), vreinterpret_u16_u8(y)); x = vreinterpret_u8_u16(t.val[0]); y = vreinterpret_u8_u16(t.val[1]); } +#define dct_trn8_32(x, y) { uint32x2x2_t t = vtrn_u32(vreinterpret_u32_u8(x), vreinterpret_u32_u8(y)); x = vreinterpret_u8_u32(t.val[0]); y = vreinterpret_u8_u32(t.val[1]); } + + // sadly can't use interleaved stores here since we only write + // 8 bytes to each scan line! + + // 8x8 8-bit transpose pass 1 + dct_trn8_8(p0, p1); + dct_trn8_8(p2, p3); + dct_trn8_8(p4, p5); + dct_trn8_8(p6, p7); + + // pass 2 + dct_trn8_16(p0, p2); + dct_trn8_16(p1, p3); + dct_trn8_16(p4, p6); + dct_trn8_16(p5, p7); + + // pass 3 + dct_trn8_32(p0, p4); + dct_trn8_32(p1, p5); + dct_trn8_32(p2, p6); + dct_trn8_32(p3, p7); + + // store + vst1_u8(out, p0); out += out_stride; + vst1_u8(out, p1); out += out_stride; + vst1_u8(out, p2); out += out_stride; + vst1_u8(out, p3); out += out_stride; + vst1_u8(out, p4); out += out_stride; + vst1_u8(out, p5); out += out_stride; + vst1_u8(out, p6); out += out_stride; + vst1_u8(out, p7); + +#undef dct_trn8_8 +#undef dct_trn8_16 +#undef dct_trn8_32 + } + +#undef dct_long_mul +#undef dct_long_mac +#undef dct_widen +#undef dct_wadd +#undef dct_wsub +#undef dct_bfly32o +#undef dct_pass +} + +#endif // STBI_NEON + +#define STBI__MARKER_none 0xff +// if there's a pending marker from the entropy stream, return that +// otherwise, fetch from the stream and get a marker. if there's no +// marker, return 0xff, which is never a valid marker value +static stbi_uc stbi__get_marker(stbi__jpeg *j) +{ + stbi_uc x; + if (j->marker != STBI__MARKER_none) { x = j->marker; j->marker = STBI__MARKER_none; return x; } + x = stbi__get8(j->s); + if (x != 0xff) return STBI__MARKER_none; + while (x == 0xff) + x = stbi__get8(j->s); // consume repeated 0xff fill bytes + return x; +} + +// in each scan, we'll have scan_n components, and the order +// of the components is specified by order[] +#define STBI__RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) + +// after a restart interval, stbi__jpeg_reset the entropy decoder and +// the dc prediction +static void stbi__jpeg_reset(stbi__jpeg *j) +{ + j->code_bits = 0; + j->code_buffer = 0; + j->nomore = 0; + j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0; + j->marker = STBI__MARKER_none; + j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; + j->eob_run = 0; + // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, + // since we don't even allow 1<<30 pixels +} + +static int stbi__parse_entropy_coded_data(stbi__jpeg *z) +{ + stbi__jpeg_reset(z); + if (!z->progressive) { + if (z->scan_n == 1) { + int i,j; + STBI_SIMD_ALIGN(short, data[64]); + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + // if it's NOT a restart, then just bail, so we get corrupt data + // rather than no data + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } else { // interleaved + int i,j,k,x,y; + STBI_SIMD_ALIGN(short, data[64]); + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x)*8; + int y2 = (j*z->img_comp[n].v + y)*8; + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+ha, z->fast_ac[ha], n, z->dequant[z->img_comp[n].tq])) return 0; + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data); + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + } else { + if (z->scan_n == 1) { + int i,j; + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + if (z->spec_start == 0) { + if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } else { + int ha = z->img_comp[n].ha; + if (!stbi__jpeg_decode_block_prog_ac(z, data, &z->huff_ac[ha], z->fast_ac[ha])) + return 0; + } + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } else { // interleaved + int i,j,k,x,y; + for (j=0; j < z->img_mcu_y; ++j) { + for (i=0; i < z->img_mcu_x; ++i) { + // scan an interleaved mcu... process scan_n components in order + for (k=0; k < z->scan_n; ++k) { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y=0; y < z->img_comp[n].v; ++y) { + for (x=0; x < z->img_comp[n].h; ++x) { + int x2 = (i*z->img_comp[n].h + x); + int y2 = (j*z->img_comp[n].v + y); + short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w); + if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n)) + return 0; + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) { + if (z->code_bits < 24) stbi__grow_buffer_unsafe(z); + if (!STBI__RESTART(z->marker)) return 1; + stbi__jpeg_reset(z); + } + } + } + return 1; + } + } +} + +static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant) +{ + int i; + for (i=0; i < 64; ++i) + data[i] *= dequant[i]; +} + +static void stbi__jpeg_finish(stbi__jpeg *z) +{ + if (z->progressive) { + // dequantize and idct the data + int i,j,n; + for (n=0; n < z->s->img_n; ++n) { + int w = (z->img_comp[n].x+7) >> 3; + int h = (z->img_comp[n].y+7) >> 3; + for (j=0; j < h; ++j) { + for (i=0; i < w; ++i) { + short *data = z->img_comp[n].coeff + 64 * (i + j * z->img_comp[n].coeff_w); + stbi__jpeg_dequantize(data, z->dequant[z->img_comp[n].tq]); + z->idct_block_kernel(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data); + } + } + } + } +} + +static int stbi__process_marker(stbi__jpeg *z, int m) +{ + int L; + switch (m) { + case STBI__MARKER_none: // no marker found + return stbi__err("expected marker","Corrupt JPEG"); + + case 0xDD: // DRI - specify restart interval + if (stbi__get16be(z->s) != 4) return stbi__err("bad DRI len","Corrupt JPEG"); + z->restart_interval = stbi__get16be(z->s); + return 1; + + case 0xDB: // DQT - define quantization table + L = stbi__get16be(z->s)-2; + while (L > 0) { + int q = stbi__get8(z->s); + int p = q >> 4, sixteen = (p != 0); + int t = q & 15,i; + if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG"); + if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG"); + + for (i=0; i < 64; ++i) + z->dequant[t][stbi__jpeg_dezigzag[i]] = (stbi__uint16)(sixteen ? stbi__get16be(z->s) : stbi__get8(z->s)); + L -= (sixteen ? 129 : 65); + } + return L==0; + + case 0xC4: // DHT - define huffman table + L = stbi__get16be(z->s)-2; + while (L > 0) { + stbi_uc *v; + int sizes[16],i,n=0; + int q = stbi__get8(z->s); + int tc = q >> 4; + int th = q & 15; + if (tc > 1 || th > 3) return stbi__err("bad DHT header","Corrupt JPEG"); + for (i=0; i < 16; ++i) { + sizes[i] = stbi__get8(z->s); + n += sizes[i]; + } + L -= 17; + if (tc == 0) { + if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0; + v = z->huff_dc[th].values; + } else { + if (!stbi__build_huffman(z->huff_ac+th, sizes)) return 0; + v = z->huff_ac[th].values; + } + for (i=0; i < n; ++i) + v[i] = stbi__get8(z->s); + if (tc != 0) + stbi__build_fast_ac(z->fast_ac[th], z->huff_ac + th); + L -= n; + } + return L==0; + } + + // check for comment block or APP blocks + if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { + L = stbi__get16be(z->s); + if (L < 2) { + if (m == 0xFE) + return stbi__err("bad COM len","Corrupt JPEG"); + else + return stbi__err("bad APP len","Corrupt JPEG"); + } + L -= 2; + + if (m == 0xE0 && L >= 5) { // JFIF APP0 segment + static const unsigned char tag[5] = {'J','F','I','F','\0'}; + int ok = 1; + int i; + for (i=0; i < 5; ++i) + if (stbi__get8(z->s) != tag[i]) + ok = 0; + L -= 5; + if (ok) + z->jfif = 1; + } else if (m == 0xEE && L >= 12) { // Adobe APP14 segment + static const unsigned char tag[6] = {'A','d','o','b','e','\0'}; + int ok = 1; + int i; + for (i=0; i < 6; ++i) + if (stbi__get8(z->s) != tag[i]) + ok = 0; + L -= 6; + if (ok) { + stbi__get8(z->s); // version + stbi__get16be(z->s); // flags0 + stbi__get16be(z->s); // flags1 + z->app14_color_transform = stbi__get8(z->s); // color transform + L -= 6; + } + } + + stbi__skip(z->s, L); + return 1; + } + + return stbi__err("unknown marker","Corrupt JPEG"); +} + +// after we see SOS +static int stbi__process_scan_header(stbi__jpeg *z) +{ + int i; + int Ls = stbi__get16be(z->s); + z->scan_n = stbi__get8(z->s); + if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return stbi__err("bad SOS component count","Corrupt JPEG"); + if (Ls != 6+2*z->scan_n) return stbi__err("bad SOS len","Corrupt JPEG"); + for (i=0; i < z->scan_n; ++i) { + int id = stbi__get8(z->s), which; + int q = stbi__get8(z->s); + for (which = 0; which < z->s->img_n; ++which) + if (z->img_comp[which].id == id) + break; + if (which == z->s->img_n) return 0; // no match + z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return stbi__err("bad DC huff","Corrupt JPEG"); + z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return stbi__err("bad AC huff","Corrupt JPEG"); + z->order[i] = which; + } + + { + int aa; + z->spec_start = stbi__get8(z->s); + z->spec_end = stbi__get8(z->s); // should be 63, but might be 0 + aa = stbi__get8(z->s); + z->succ_high = (aa >> 4); + z->succ_low = (aa & 15); + if (z->progressive) { + if (z->spec_start > 63 || z->spec_end > 63 || z->spec_start > z->spec_end || z->succ_high > 13 || z->succ_low > 13) + return stbi__err("bad SOS", "Corrupt JPEG"); + } else { + if (z->spec_start != 0) return stbi__err("bad SOS","Corrupt JPEG"); + if (z->succ_high != 0 || z->succ_low != 0) return stbi__err("bad SOS","Corrupt JPEG"); + z->spec_end = 63; + } + } + + return 1; +} + +static int stbi__free_jpeg_components(stbi__jpeg *z, int ncomp, int why) +{ + int i; + for (i=0; i < ncomp; ++i) { + if (z->img_comp[i].raw_data) { + STBI_FREE(z->img_comp[i].raw_data); + z->img_comp[i].raw_data = NULL; + z->img_comp[i].data = NULL; + } + if (z->img_comp[i].raw_coeff) { + STBI_FREE(z->img_comp[i].raw_coeff); + z->img_comp[i].raw_coeff = 0; + z->img_comp[i].coeff = 0; + } + if (z->img_comp[i].linebuf) { + STBI_FREE(z->img_comp[i].linebuf); + z->img_comp[i].linebuf = NULL; + } + } + return why; +} + +static int stbi__process_frame_header(stbi__jpeg *z, int scan) +{ + stbi__context *s = z->s; + int Lf,p,i,q, h_max=1,v_max=1,c; + Lf = stbi__get16be(s); if (Lf < 11) return stbi__err("bad SOF len","Corrupt JPEG"); // JPEG + p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline + s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG + s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires + c = stbi__get8(s); + if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG"); + s->img_n = c; + for (i=0; i < c; ++i) { + z->img_comp[i].data = NULL; + z->img_comp[i].linebuf = NULL; + } + + if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG"); + + z->rgb = 0; + for (i=0; i < s->img_n; ++i) { + static const unsigned char rgb[3] = { 'R', 'G', 'B' }; + z->img_comp[i].id = stbi__get8(s); + if (s->img_n == 3 && z->img_comp[i].id == rgb[i]) + ++z->rgb; + q = stbi__get8(s); + z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG"); + z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG"); + z->img_comp[i].tq = stbi__get8(s); if (z->img_comp[i].tq > 3) return stbi__err("bad TQ","Corrupt JPEG"); + } + + if (scan != STBI__SCAN_load) return 1; + + if (!stbi__mad3sizes_valid(s->img_x, s->img_y, s->img_n, 0)) return stbi__err("too large", "Image too large to decode"); + + for (i=0; i < s->img_n; ++i) { + if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; + if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; + } + + // compute interleaved mcu info + z->img_h_max = h_max; + z->img_v_max = v_max; + z->img_mcu_w = h_max * 8; + z->img_mcu_h = v_max * 8; + // these sizes can't be more than 17 bits + z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; + z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; + + for (i=0; i < s->img_n; ++i) { + // number of effective pixels (e.g. for non-interleaved MCU) + z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; + z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; + // to simplify generation, we'll allocate enough memory to decode + // the bogus oversized data from using interleaved MCUs and their + // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't + // discard the extra data until colorspace conversion + // + // img_mcu_x, img_mcu_y: <=17 bits; comp[i].h and .v are <=4 (checked earlier) + // so these muls can't overflow with 32-bit ints (which we require) + z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; + z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; + z->img_comp[i].coeff = 0; + z->img_comp[i].raw_coeff = 0; + z->img_comp[i].linebuf = NULL; + z->img_comp[i].raw_data = stbi__malloc_mad2(z->img_comp[i].w2, z->img_comp[i].h2, 15); + if (z->img_comp[i].raw_data == NULL) + return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); + // align blocks for idct using mmx/sse + z->img_comp[i].data = (stbi_uc*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); + if (z->progressive) { + // w2, h2 are multiples of 8 (see above) + z->img_comp[i].coeff_w = z->img_comp[i].w2 / 8; + z->img_comp[i].coeff_h = z->img_comp[i].h2 / 8; + z->img_comp[i].raw_coeff = stbi__malloc_mad3(z->img_comp[i].w2, z->img_comp[i].h2, sizeof(short), 15); + if (z->img_comp[i].raw_coeff == NULL) + return stbi__free_jpeg_components(z, i+1, stbi__err("outofmem", "Out of memory")); + z->img_comp[i].coeff = (short*) (((size_t) z->img_comp[i].raw_coeff + 15) & ~15); + } + } + + return 1; +} + +// use comparisons since in some cases we handle more than one case (e.g. SOF) +#define stbi__DNL(x) ((x) == 0xdc) +#define stbi__SOI(x) ((x) == 0xd8) +#define stbi__EOI(x) ((x) == 0xd9) +#define stbi__SOF(x) ((x) == 0xc0 || (x) == 0xc1 || (x) == 0xc2) +#define stbi__SOS(x) ((x) == 0xda) + +#define stbi__SOF_progressive(x) ((x) == 0xc2) + +static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan) +{ + int m; + z->jfif = 0; + z->app14_color_transform = -1; // valid values are 0,1,2 + z->marker = STBI__MARKER_none; // initialize cached marker to empty + m = stbi__get_marker(z); + if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG"); + if (scan == STBI__SCAN_type) return 1; + m = stbi__get_marker(z); + while (!stbi__SOF(m)) { + if (!stbi__process_marker(z,m)) return 0; + m = stbi__get_marker(z); + while (m == STBI__MARKER_none) { + // some files have extra padding after their blocks, so ok, we'll scan + if (stbi__at_eof(z->s)) return stbi__err("no SOF", "Corrupt JPEG"); + m = stbi__get_marker(z); + } + } + z->progressive = stbi__SOF_progressive(m); + if (!stbi__process_frame_header(z, scan)) return 0; + return 1; +} + +// decode image to YCbCr format +static int stbi__decode_jpeg_image(stbi__jpeg *j) +{ + int m; + for (m = 0; m < 4; m++) { + j->img_comp[m].raw_data = NULL; + j->img_comp[m].raw_coeff = NULL; + } + j->restart_interval = 0; + if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0; + m = stbi__get_marker(j); + while (!stbi__EOI(m)) { + if (stbi__SOS(m)) { + if (!stbi__process_scan_header(j)) return 0; + if (!stbi__parse_entropy_coded_data(j)) return 0; + if (j->marker == STBI__MARKER_none ) { + // handle 0s at the end of image data from IP Kamera 9060 + while (!stbi__at_eof(j->s)) { + int x = stbi__get8(j->s); + if (x == 255) { + j->marker = stbi__get8(j->s); + break; + } + } + // if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0 + } + } else if (stbi__DNL(m)) { + int Ld = stbi__get16be(j->s); + stbi__uint32 NL = stbi__get16be(j->s); + if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG"); + if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG"); + } else { + if (!stbi__process_marker(j, m)) return 0; + } + m = stbi__get_marker(j); + } + if (j->progressive) + stbi__jpeg_finish(j); + return 1; +} + +// static jfif-centered resampling (across block boundaries) + +typedef stbi_uc *(*resample_row_func)(stbi_uc *out, stbi_uc *in0, stbi_uc *in1, + int w, int hs); + +#define stbi__div4(x) ((stbi_uc) ((x) >> 2)) + +static stbi_uc *resample_row_1(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + STBI_NOTUSED(out); + STBI_NOTUSED(in_far); + STBI_NOTUSED(w); + STBI_NOTUSED(hs); + return in_near; +} + +static stbi_uc* stbi__resample_row_v_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate two samples vertically for every one in input + int i; + STBI_NOTUSED(hs); + for (i=0; i < w; ++i) + out[i] = stbi__div4(3*in_near[i] + in_far[i] + 2); + return out; +} + +static stbi_uc* stbi__resample_row_h_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate two samples horizontally for every one in input + int i; + stbi_uc *input = in_near; + + if (w == 1) { + // if only one sample, can't do any interpolation + out[0] = out[1] = input[0]; + return out; + } + + out[0] = input[0]; + out[1] = stbi__div4(input[0]*3 + input[1] + 2); + for (i=1; i < w-1; ++i) { + int n = 3*input[i]+2; + out[i*2+0] = stbi__div4(n+input[i-1]); + out[i*2+1] = stbi__div4(n+input[i+1]); + } + out[i*2+0] = stbi__div4(input[w-2]*3 + input[w-1] + 2); + out[i*2+1] = input[w-1]; + + STBI_NOTUSED(in_far); + STBI_NOTUSED(hs); + + return out; +} + +#define stbi__div16(x) ((stbi_uc) ((x) >> 4)) + +static stbi_uc *stbi__resample_row_hv_2(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i,t0,t1; + if (w == 1) { + out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + out[0] = stbi__div4(t1+2); + for (i=1; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = stbi__div16(3*t0 + t1 + 8); + out[i*2 ] = stbi__div16(3*t1 + t0 + 8); + } + out[w*2-1] = stbi__div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} + +#if defined(STBI_SSE2) || defined(STBI_NEON) +static stbi_uc *stbi__resample_row_hv_2_simd(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // need to generate 2x2 samples for every one in input + int i=0,t0,t1; + + if (w == 1) { + out[0] = out[1] = stbi__div4(3*in_near[0] + in_far[0] + 2); + return out; + } + + t1 = 3*in_near[0] + in_far[0]; + // process groups of 8 pixels for as long as we can. + // note we can't handle the last pixel in a row in this loop + // because we need to handle the filter boundary conditions. + for (; i < ((w-1) & ~7); i += 8) { +#if defined(STBI_SSE2) + // load and perform the vertical filtering pass + // this uses 3*x + y = 4*x + (y - x) + __m128i zero = _mm_setzero_si128(); + __m128i farb = _mm_loadl_epi64((__m128i *) (in_far + i)); + __m128i nearb = _mm_loadl_epi64((__m128i *) (in_near + i)); + __m128i farw = _mm_unpacklo_epi8(farb, zero); + __m128i nearw = _mm_unpacklo_epi8(nearb, zero); + __m128i diff = _mm_sub_epi16(farw, nearw); + __m128i nears = _mm_slli_epi16(nearw, 2); + __m128i curr = _mm_add_epi16(nears, diff); // current row + + // horizontal filter works the same based on shifted vers of current + // row. "prev" is current row shifted right by 1 pixel; we need to + // insert the previous pixel value (from t1). + // "next" is current row shifted left by 1 pixel, with first pixel + // of next block of 8 pixels added in. + __m128i prv0 = _mm_slli_si128(curr, 2); + __m128i nxt0 = _mm_srli_si128(curr, 2); + __m128i prev = _mm_insert_epi16(prv0, t1, 0); + __m128i next = _mm_insert_epi16(nxt0, 3*in_near[i+8] + in_far[i+8], 7); + + // horizontal filter, polyphase implementation since it's convenient: + // even pixels = 3*cur + prev = cur*4 + (prev - cur) + // odd pixels = 3*cur + next = cur*4 + (next - cur) + // note the shared term. + __m128i bias = _mm_set1_epi16(8); + __m128i curs = _mm_slli_epi16(curr, 2); + __m128i prvd = _mm_sub_epi16(prev, curr); + __m128i nxtd = _mm_sub_epi16(next, curr); + __m128i curb = _mm_add_epi16(curs, bias); + __m128i even = _mm_add_epi16(prvd, curb); + __m128i odd = _mm_add_epi16(nxtd, curb); + + // interleave even and odd pixels, then undo scaling. + __m128i int0 = _mm_unpacklo_epi16(even, odd); + __m128i int1 = _mm_unpackhi_epi16(even, odd); + __m128i de0 = _mm_srli_epi16(int0, 4); + __m128i de1 = _mm_srli_epi16(int1, 4); + + // pack and write output + __m128i outv = _mm_packus_epi16(de0, de1); + _mm_storeu_si128((__m128i *) (out + i*2), outv); +#elif defined(STBI_NEON) + // load and perform the vertical filtering pass + // this uses 3*x + y = 4*x + (y - x) + uint8x8_t farb = vld1_u8(in_far + i); + uint8x8_t nearb = vld1_u8(in_near + i); + int16x8_t diff = vreinterpretq_s16_u16(vsubl_u8(farb, nearb)); + int16x8_t nears = vreinterpretq_s16_u16(vshll_n_u8(nearb, 2)); + int16x8_t curr = vaddq_s16(nears, diff); // current row + + // horizontal filter works the same based on shifted vers of current + // row. "prev" is current row shifted right by 1 pixel; we need to + // insert the previous pixel value (from t1). + // "next" is current row shifted left by 1 pixel, with first pixel + // of next block of 8 pixels added in. + int16x8_t prv0 = vextq_s16(curr, curr, 7); + int16x8_t nxt0 = vextq_s16(curr, curr, 1); + int16x8_t prev = vsetq_lane_s16(t1, prv0, 0); + int16x8_t next = vsetq_lane_s16(3*in_near[i+8] + in_far[i+8], nxt0, 7); + + // horizontal filter, polyphase implementation since it's convenient: + // even pixels = 3*cur + prev = cur*4 + (prev - cur) + // odd pixels = 3*cur + next = cur*4 + (next - cur) + // note the shared term. + int16x8_t curs = vshlq_n_s16(curr, 2); + int16x8_t prvd = vsubq_s16(prev, curr); + int16x8_t nxtd = vsubq_s16(next, curr); + int16x8_t even = vaddq_s16(curs, prvd); + int16x8_t odd = vaddq_s16(curs, nxtd); + + // undo scaling and round, then store with even/odd phases interleaved + uint8x8x2_t o; + o.val[0] = vqrshrun_n_s16(even, 4); + o.val[1] = vqrshrun_n_s16(odd, 4); + vst2_u8(out + i*2, o); +#endif + + // "previous" value for next iter + t1 = 3*in_near[i+7] + in_far[i+7]; + } + + t0 = t1; + t1 = 3*in_near[i] + in_far[i]; + out[i*2] = stbi__div16(3*t1 + t0 + 8); + + for (++i; i < w; ++i) { + t0 = t1; + t1 = 3*in_near[i]+in_far[i]; + out[i*2-1] = stbi__div16(3*t0 + t1 + 8); + out[i*2 ] = stbi__div16(3*t1 + t0 + 8); + } + out[w*2-1] = stbi__div4(t1+2); + + STBI_NOTUSED(hs); + + return out; +} +#endif + +static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_uc *in_far, int w, int hs) +{ + // resample with nearest-neighbor + int i,j; + STBI_NOTUSED(in_far); + for (i=0; i < w; ++i) + for (j=0; j < hs; ++j) + out[i*hs+j] = in_near[i]; + return out; +} + +// this is a reduced-precision calculation of YCbCr-to-RGB introduced +// to make sure the code produces the same results in both SIMD and scalar +#define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8) +static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step) +{ + int i; + for (i=0; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1<<19); // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr* stbi__float2fixed(1.40200f); + g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* stbi__float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} + +#if defined(STBI_SSE2) || defined(STBI_NEON) +static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step) +{ + int i = 0; + +#ifdef STBI_SSE2 + // step == 3 is pretty ugly on the final interleave, and i'm not convinced + // it's useful in practice (you wouldn't use it for textures, for example). + // so just accelerate step == 4 case. + if (step == 4) { + // this is a fairly straightforward implementation and not super-optimized. + __m128i signflip = _mm_set1_epi8(-0x80); + __m128i cr_const0 = _mm_set1_epi16( (short) ( 1.40200f*4096.0f+0.5f)); + __m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f)); + __m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f)); + __m128i cb_const1 = _mm_set1_epi16( (short) ( 1.77200f*4096.0f+0.5f)); + __m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128); + __m128i xw = _mm_set1_epi16(255); // alpha channel + + for (; i+7 < count; i += 8) { + // load + __m128i y_bytes = _mm_loadl_epi64((__m128i *) (y+i)); + __m128i cr_bytes = _mm_loadl_epi64((__m128i *) (pcr+i)); + __m128i cb_bytes = _mm_loadl_epi64((__m128i *) (pcb+i)); + __m128i cr_biased = _mm_xor_si128(cr_bytes, signflip); // -128 + __m128i cb_biased = _mm_xor_si128(cb_bytes, signflip); // -128 + + // unpack to short (and left-shift cr, cb by 8) + __m128i yw = _mm_unpacklo_epi8(y_bias, y_bytes); + __m128i crw = _mm_unpacklo_epi8(_mm_setzero_si128(), cr_biased); + __m128i cbw = _mm_unpacklo_epi8(_mm_setzero_si128(), cb_biased); + + // color transform + __m128i yws = _mm_srli_epi16(yw, 4); + __m128i cr0 = _mm_mulhi_epi16(cr_const0, crw); + __m128i cb0 = _mm_mulhi_epi16(cb_const0, cbw); + __m128i cb1 = _mm_mulhi_epi16(cbw, cb_const1); + __m128i cr1 = _mm_mulhi_epi16(crw, cr_const1); + __m128i rws = _mm_add_epi16(cr0, yws); + __m128i gwt = _mm_add_epi16(cb0, yws); + __m128i bws = _mm_add_epi16(yws, cb1); + __m128i gws = _mm_add_epi16(gwt, cr1); + + // descale + __m128i rw = _mm_srai_epi16(rws, 4); + __m128i bw = _mm_srai_epi16(bws, 4); + __m128i gw = _mm_srai_epi16(gws, 4); + + // back to byte, set up for transpose + __m128i brb = _mm_packus_epi16(rw, bw); + __m128i gxb = _mm_packus_epi16(gw, xw); + + // transpose to interleave channels + __m128i t0 = _mm_unpacklo_epi8(brb, gxb); + __m128i t1 = _mm_unpackhi_epi8(brb, gxb); + __m128i o0 = _mm_unpacklo_epi16(t0, t1); + __m128i o1 = _mm_unpackhi_epi16(t0, t1); + + // store + _mm_storeu_si128((__m128i *) (out + 0), o0); + _mm_storeu_si128((__m128i *) (out + 16), o1); + out += 32; + } + } +#endif + +#ifdef STBI_NEON + // in this version, step=3 support would be easy to add. but is there demand? + if (step == 4) { + // this is a fairly straightforward implementation and not super-optimized. + uint8x8_t signflip = vdup_n_u8(0x80); + int16x8_t cr_const0 = vdupq_n_s16( (short) ( 1.40200f*4096.0f+0.5f)); + int16x8_t cr_const1 = vdupq_n_s16( - (short) ( 0.71414f*4096.0f+0.5f)); + int16x8_t cb_const0 = vdupq_n_s16( - (short) ( 0.34414f*4096.0f+0.5f)); + int16x8_t cb_const1 = vdupq_n_s16( (short) ( 1.77200f*4096.0f+0.5f)); + + for (; i+7 < count; i += 8) { + // load + uint8x8_t y_bytes = vld1_u8(y + i); + uint8x8_t cr_bytes = vld1_u8(pcr + i); + uint8x8_t cb_bytes = vld1_u8(pcb + i); + int8x8_t cr_biased = vreinterpret_s8_u8(vsub_u8(cr_bytes, signflip)); + int8x8_t cb_biased = vreinterpret_s8_u8(vsub_u8(cb_bytes, signflip)); + + // expand to s16 + int16x8_t yws = vreinterpretq_s16_u16(vshll_n_u8(y_bytes, 4)); + int16x8_t crw = vshll_n_s8(cr_biased, 7); + int16x8_t cbw = vshll_n_s8(cb_biased, 7); + + // color transform + int16x8_t cr0 = vqdmulhq_s16(crw, cr_const0); + int16x8_t cb0 = vqdmulhq_s16(cbw, cb_const0); + int16x8_t cr1 = vqdmulhq_s16(crw, cr_const1); + int16x8_t cb1 = vqdmulhq_s16(cbw, cb_const1); + int16x8_t rws = vaddq_s16(yws, cr0); + int16x8_t gws = vaddq_s16(vaddq_s16(yws, cb0), cr1); + int16x8_t bws = vaddq_s16(yws, cb1); + + // undo scaling, round, convert to byte + uint8x8x4_t o; + o.val[0] = vqrshrun_n_s16(rws, 4); + o.val[1] = vqrshrun_n_s16(gws, 4); + o.val[2] = vqrshrun_n_s16(bws, 4); + o.val[3] = vdup_n_u8(255); + + // store, interleaving r/g/b/a + vst4_u8(out, o); + out += 8*4; + } + } +#endif + + for (; i < count; ++i) { + int y_fixed = (y[i] << 20) + (1<<19); // rounding + int r,g,b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr* stbi__float2fixed(1.40200f); + g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000); + b = y_fixed + cb* stbi__float2fixed(1.77200f); + r >>= 20; + g >>= 20; + b >>= 20; + if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } + if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } + if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } + out[0] = (stbi_uc)r; + out[1] = (stbi_uc)g; + out[2] = (stbi_uc)b; + out[3] = 255; + out += step; + } +} +#endif + +// set up the kernels +static void stbi__setup_jpeg(stbi__jpeg *j) +{ + j->idct_block_kernel = stbi__idct_block; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_row; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2; + +#ifdef STBI_SSE2 + if (stbi__sse2_available()) { + j->idct_block_kernel = stbi__idct_simd; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; + } +#endif + +#ifdef STBI_NEON + j->idct_block_kernel = stbi__idct_simd; + j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd; + j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd; +#endif +} + +// clean up the temporary component buffers +static void stbi__cleanup_jpeg(stbi__jpeg *j) +{ + stbi__free_jpeg_components(j, j->s->img_n, 0); +} + +typedef struct +{ + resample_row_func resample; + stbi_uc *line0,*line1; + int hs,vs; // expansion factor in each axis + int w_lores; // horizontal pixels pre-expansion + int ystep; // how far through vertical expansion we are + int ypos; // which pre-expansion row we're on +} stbi__resample; + +// fast 0..255 * 0..255 => 0..255 rounded multiplication +static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y) +{ + unsigned int t = x*y + 128; + return (stbi_uc) ((t + (t >>8)) >> 8); +} + +static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) +{ + int n, decode_n, is_rgb; + z->s->img_n = 0; // make stbi__cleanup_jpeg safe + + // validate req_comp + if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + + // load a jpeg image from whichever source, but leave in YCbCr format + if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; } + + // determine actual number of components to generate + n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1; + + is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif)); + + if (z->s->img_n == 3 && n < 3 && !is_rgb) + decode_n = 1; + else + decode_n = z->s->img_n; + + // resample and color-convert + { + int k; + unsigned int i,j; + stbi_uc *output; + stbi_uc *coutput[4] = { NULL, NULL, NULL, NULL }; + + stbi__resample res_comp[4]; + + for (k=0; k < decode_n; ++k) { + stbi__resample *r = &res_comp[k]; + + // allocate line buffer big enough for upsampling off the edges + // with upsample factor of 4 + z->img_comp[k].linebuf = (stbi_uc *) stbi__malloc(z->s->img_x + 3); + if (!z->img_comp[k].linebuf) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } + + r->hs = z->img_h_max / z->img_comp[k].h; + r->vs = z->img_v_max / z->img_comp[k].v; + r->ystep = r->vs >> 1; + r->w_lores = (z->s->img_x + r->hs-1) / r->hs; + r->ypos = 0; + r->line0 = r->line1 = z->img_comp[k].data; + + if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; + else if (r->hs == 1 && r->vs == 2) r->resample = stbi__resample_row_v_2; + else if (r->hs == 2 && r->vs == 1) r->resample = stbi__resample_row_h_2; + else if (r->hs == 2 && r->vs == 2) r->resample = z->resample_row_hv_2_kernel; + else r->resample = stbi__resample_row_generic; + } + + // can't error after this so, this is safe + output = (stbi_uc *) stbi__malloc_mad3(n, z->s->img_x, z->s->img_y, 1); + if (!output) { stbi__cleanup_jpeg(z); return stbi__errpuc("outofmem", "Out of memory"); } + + // now go ahead and resample + for (j=0; j < z->s->img_y; ++j) { + stbi_uc *out = output + n * z->s->img_x * j; + for (k=0; k < decode_n; ++k) { + stbi__resample *r = &res_comp[k]; + int y_bot = r->ystep >= (r->vs >> 1); + coutput[k] = r->resample(z->img_comp[k].linebuf, + y_bot ? r->line1 : r->line0, + y_bot ? r->line0 : r->line1, + r->w_lores, r->hs); + if (++r->ystep >= r->vs) { + r->ystep = 0; + r->line0 = r->line1; + if (++r->ypos < z->img_comp[k].y) + r->line1 += z->img_comp[k].w2; + } + } + if (n >= 3) { + stbi_uc *y = coutput[0]; + if (z->s->img_n == 3) { + if (is_rgb) { + for (i=0; i < z->s->img_x; ++i) { + out[0] = y[i]; + out[1] = coutput[1][i]; + out[2] = coutput[2][i]; + out[3] = 255; + out += n; + } + } else { + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + } + } else if (z->s->img_n == 4) { + if (z->app14_color_transform == 0) { // CMYK + for (i=0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + out[0] = stbi__blinn_8x8(coutput[0][i], m); + out[1] = stbi__blinn_8x8(coutput[1][i], m); + out[2] = stbi__blinn_8x8(coutput[2][i], m); + out[3] = 255; + out += n; + } + } else if (z->app14_color_transform == 2) { // YCCK + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + for (i=0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + out[0] = stbi__blinn_8x8(255 - out[0], m); + out[1] = stbi__blinn_8x8(255 - out[1], m); + out[2] = stbi__blinn_8x8(255 - out[2], m); + out += n; + } + } else { // YCbCr + alpha? Ignore the fourth channel for now + z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n); + } + } else + for (i=0; i < z->s->img_x; ++i) { + out[0] = out[1] = out[2] = y[i]; + out[3] = 255; // not used if n==3 + out += n; + } + } else { + if (is_rgb) { + if (n == 1) + for (i=0; i < z->s->img_x; ++i) + *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); + else { + for (i=0; i < z->s->img_x; ++i, out += 2) { + out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]); + out[1] = 255; + } + } + } else if (z->s->img_n == 4 && z->app14_color_transform == 0) { + for (i=0; i < z->s->img_x; ++i) { + stbi_uc m = coutput[3][i]; + stbi_uc r = stbi__blinn_8x8(coutput[0][i], m); + stbi_uc g = stbi__blinn_8x8(coutput[1][i], m); + stbi_uc b = stbi__blinn_8x8(coutput[2][i], m); + out[0] = stbi__compute_y(r, g, b); + out[1] = 255; + out += n; + } + } else if (z->s->img_n == 4 && z->app14_color_transform == 2) { + for (i=0; i < z->s->img_x; ++i) { + out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]); + out[1] = 255; + out += n; + } + } else { + stbi_uc *y = coutput[0]; + if (n == 1) + for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; + else + for (i=0; i < z->s->img_x; ++i) { *out++ = y[i]; *out++ = 255; } + } + } + } + stbi__cleanup_jpeg(z); + *out_x = z->s->img_x; + *out_y = z->s->img_y; + if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output + return output; + } +} + +static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + unsigned char* result; + stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg)); + STBI_NOTUSED(ri); + j->s = s; + stbi__setup_jpeg(j); + result = load_jpeg_image(j, x,y,comp,req_comp); + STBI_FREE(j); + return result; +} + +static int stbi__jpeg_test(stbi__context *s) +{ + int r; + stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg)); + j->s = s; + stbi__setup_jpeg(j); + r = stbi__decode_jpeg_header(j, STBI__SCAN_type); + stbi__rewind(s); + STBI_FREE(j); + return r; +} + +static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp) +{ + if (!stbi__decode_jpeg_header(j, STBI__SCAN_header)) { + stbi__rewind( j->s ); + return 0; + } + if (x) *x = j->s->img_x; + if (y) *y = j->s->img_y; + if (comp) *comp = j->s->img_n >= 3 ? 3 : 1; + return 1; +} + +static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp) +{ + int result; + stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg))); + j->s = s; + result = stbi__jpeg_info_raw(j, x, y, comp); + STBI_FREE(j); + return result; +} +#endif + +// public domain zlib decode v0.2 Sean Barrett 2006-11-18 +// simple implementation +// - all input must be provided in an upfront buffer +// - all output is written to a single output buffer (can malloc/realloc) +// performance +// - fast huffman + +#ifndef STBI_NO_ZLIB + +// fast-way is faster to check than jpeg huffman, but slow way is slower +#define STBI__ZFAST_BITS 9 // accelerate all cases in default tables +#define STBI__ZFAST_MASK ((1 << STBI__ZFAST_BITS) - 1) + +// zlib-style huffman encoding +// (jpegs packs from left, zlib from right, so can't share code) +typedef struct +{ + stbi__uint16 fast[1 << STBI__ZFAST_BITS]; + stbi__uint16 firstcode[16]; + int maxcode[17]; + stbi__uint16 firstsymbol[16]; + stbi_uc size[288]; + stbi__uint16 value[288]; +} stbi__zhuffman; + +stbi_inline static int stbi__bitreverse16(int n) +{ + n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); + n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); + n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); + n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); + return n; +} + +stbi_inline static int stbi__bit_reverse(int v, int bits) +{ + STBI_ASSERT(bits <= 16); + // to bit reverse n bits, reverse 16 and shift + // e.g. 11 bits, bit reverse and shift away 5 + return stbi__bitreverse16(v) >> (16-bits); +} + +static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num) +{ + int i,k=0; + int code, next_code[16], sizes[17]; + + // DEFLATE spec for generating codes + memset(sizes, 0, sizeof(sizes)); + memset(z->fast, 0, sizeof(z->fast)); + for (i=0; i < num; ++i) + ++sizes[sizelist[i]]; + sizes[0] = 0; + for (i=1; i < 16; ++i) + if (sizes[i] > (1 << i)) + return stbi__err("bad sizes", "Corrupt PNG"); + code = 0; + for (i=1; i < 16; ++i) { + next_code[i] = code; + z->firstcode[i] = (stbi__uint16) code; + z->firstsymbol[i] = (stbi__uint16) k; + code = (code + sizes[i]); + if (sizes[i]) + if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG"); + z->maxcode[i] = code << (16-i); // preshift for inner loop + code <<= 1; + k += sizes[i]; + } + z->maxcode[16] = 0x10000; // sentinel + for (i=0; i < num; ++i) { + int s = sizelist[i]; + if (s) { + int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; + stbi__uint16 fastv = (stbi__uint16) ((s << 9) | i); + z->size [c] = (stbi_uc ) s; + z->value[c] = (stbi__uint16) i; + if (s <= STBI__ZFAST_BITS) { + int j = stbi__bit_reverse(next_code[s],s); + while (j < (1 << STBI__ZFAST_BITS)) { + z->fast[j] = fastv; + j += (1 << s); + } + } + ++next_code[s]; + } + } + return 1; +} + +// zlib-from-memory implementation for PNG reading +// because PNG allows splitting the zlib stream arbitrarily, +// and it's annoying structurally to have PNG call ZLIB call PNG, +// we require PNG read all the IDATs and combine them into a single +// memory buffer + +typedef struct +{ + stbi_uc *zbuffer, *zbuffer_end; + int num_bits; + stbi__uint32 code_buffer; + + char *zout; + char *zout_start; + char *zout_end; + int z_expandable; + + stbi__zhuffman z_length, z_distance; +} stbi__zbuf; + +stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z) +{ + if (z->zbuffer >= z->zbuffer_end) return 0; + return *z->zbuffer++; +} + +static void stbi__fill_bits(stbi__zbuf *z) +{ + do { + STBI_ASSERT(z->code_buffer < (1U << z->num_bits)); + z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits; + z->num_bits += 8; + } while (z->num_bits <= 24); +} + +stbi_inline static unsigned int stbi__zreceive(stbi__zbuf *z, int n) +{ + unsigned int k; + if (z->num_bits < n) stbi__fill_bits(z); + k = z->code_buffer & ((1 << n) - 1); + z->code_buffer >>= n; + z->num_bits -= n; + return k; +} + +static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z) +{ + int b,s,k; + // not resolved by fast table, so compute it the slow way + // use jpeg approach, which requires MSbits at top + k = stbi__bit_reverse(a->code_buffer, 16); + for (s=STBI__ZFAST_BITS+1; ; ++s) + if (k < z->maxcode[s]) + break; + if (s == 16) return -1; // invalid code! + // code size is s, so: + b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; + STBI_ASSERT(z->size[b] == s); + a->code_buffer >>= s; + a->num_bits -= s; + return z->value[b]; +} + +stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z) +{ + int b,s; + if (a->num_bits < 16) stbi__fill_bits(a); + b = z->fast[a->code_buffer & STBI__ZFAST_MASK]; + if (b) { + s = b >> 9; + a->code_buffer >>= s; + a->num_bits -= s; + return b & 511; + } + return stbi__zhuffman_decode_slowpath(a, z); +} + +static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes +{ + char *q; + int cur, limit, old_limit; + z->zout = zout; + if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG"); + cur = (int) (z->zout - z->zout_start); + limit = old_limit = (int) (z->zout_end - z->zout_start); + while (cur + n > limit) + limit *= 2; + q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit); + STBI_NOTUSED(old_limit); + if (q == NULL) return stbi__err("outofmem", "Out of memory"); + z->zout_start = q; + z->zout = q + cur; + z->zout_end = q + limit; + return 1; +} + +static const int stbi__zlength_base[31] = { + 3,4,5,6,7,8,9,10,11,13, + 15,17,19,23,27,31,35,43,51,59, + 67,83,99,115,131,163,195,227,258,0,0 }; + +static const int stbi__zlength_extra[31]= +{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; + +static const int stbi__zdist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, +257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; + +static const int stbi__zdist_extra[32] = +{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +static int stbi__parse_huffman_block(stbi__zbuf *a) +{ + char *zout = a->zout; + for(;;) { + int z = stbi__zhuffman_decode(a, &a->z_length); + if (z < 256) { + if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); // error in huffman codes + if (zout >= a->zout_end) { + if (!stbi__zexpand(a, zout, 1)) return 0; + zout = a->zout; + } + *zout++ = (char) z; + } else { + stbi_uc *p; + int len,dist; + if (z == 256) { + a->zout = zout; + return 1; + } + z -= 257; + len = stbi__zlength_base[z]; + if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]); + z = stbi__zhuffman_decode(a, &a->z_distance); + if (z < 0) return stbi__err("bad huffman code","Corrupt PNG"); + dist = stbi__zdist_base[z]; + if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]); + if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG"); + if (zout + len > a->zout_end) { + if (!stbi__zexpand(a, zout, len)) return 0; + zout = a->zout; + } + p = (stbi_uc *) (zout - dist); + if (dist == 1) { // run of one byte; common in images. + stbi_uc v = *p; + if (len) { do *zout++ = v; while (--len); } + } else { + if (len) { do *zout++ = *p++; while (--len); } + } + } + } +} + +static int stbi__compute_huffman_codes(stbi__zbuf *a) +{ + static const stbi_uc length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + stbi__zhuffman z_codelength; + stbi_uc lencodes[286+32+137];//padding for maximum single op + stbi_uc codelength_sizes[19]; + int i,n; + + int hlit = stbi__zreceive(a,5) + 257; + int hdist = stbi__zreceive(a,5) + 1; + int hclen = stbi__zreceive(a,4) + 4; + int ntot = hlit + hdist; + + memset(codelength_sizes, 0, sizeof(codelength_sizes)); + for (i=0; i < hclen; ++i) { + int s = stbi__zreceive(a,3); + codelength_sizes[length_dezigzag[i]] = (stbi_uc) s; + } + if (!stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; + + n = 0; + while (n < ntot) { + int c = stbi__zhuffman_decode(a, &z_codelength); + if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG"); + if (c < 16) + lencodes[n++] = (stbi_uc) c; + else { + stbi_uc fill = 0; + if (c == 16) { + c = stbi__zreceive(a,2)+3; + if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG"); + fill = lencodes[n-1]; + } else if (c == 17) + c = stbi__zreceive(a,3)+3; + else { + STBI_ASSERT(c == 18); + c = stbi__zreceive(a,7)+11; + } + if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG"); + memset(lencodes+n, fill, c); + n += c; + } + } + if (n != ntot) return stbi__err("bad codelengths","Corrupt PNG"); + if (!stbi__zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; + if (!stbi__zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; + return 1; +} + +static int stbi__parse_uncompressed_block(stbi__zbuf *a) +{ + stbi_uc header[4]; + int len,nlen,k; + if (a->num_bits & 7) + stbi__zreceive(a, a->num_bits & 7); // discard + // drain the bit-packed data into header + k = 0; + while (a->num_bits > 0) { + header[k++] = (stbi_uc) (a->code_buffer & 255); // suppress MSVC run-time check + a->code_buffer >>= 8; + a->num_bits -= 8; + } + STBI_ASSERT(a->num_bits == 0); + // now fill header the normal way + while (k < 4) + header[k++] = stbi__zget8(a); + len = header[1] * 256 + header[0]; + nlen = header[3] * 256 + header[2]; + if (nlen != (len ^ 0xffff)) return stbi__err("zlib corrupt","Corrupt PNG"); + if (a->zbuffer + len > a->zbuffer_end) return stbi__err("read past buffer","Corrupt PNG"); + if (a->zout + len > a->zout_end) + if (!stbi__zexpand(a, a->zout, len)) return 0; + memcpy(a->zout, a->zbuffer, len); + a->zbuffer += len; + a->zout += len; + return 1; +} + +static int stbi__parse_zlib_header(stbi__zbuf *a) +{ + int cmf = stbi__zget8(a); + int cm = cmf & 15; + /* int cinfo = cmf >> 4; */ + int flg = stbi__zget8(a); + if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec + if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png + if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png + // window = 1 << (8 + cinfo)... but who cares, we fully buffer output + return 1; +} + +static const stbi_uc stbi__zdefault_length[288] = +{ + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, + 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8 +}; +static const stbi_uc stbi__zdefault_distance[32] = +{ + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 +}; +/* +Init algorithm: +{ + int i; // use <= to match clearly with spec + for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8; + for ( ; i <= 255; ++i) stbi__zdefault_length[i] = 9; + for ( ; i <= 279; ++i) stbi__zdefault_length[i] = 7; + for ( ; i <= 287; ++i) stbi__zdefault_length[i] = 8; + + for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5; +} +*/ + +static int stbi__parse_zlib(stbi__zbuf *a, int parse_header) +{ + int final, type; + if (parse_header) + if (!stbi__parse_zlib_header(a)) return 0; + a->num_bits = 0; + a->code_buffer = 0; + do { + final = stbi__zreceive(a,1); + type = stbi__zreceive(a,2); + if (type == 0) { + if (!stbi__parse_uncompressed_block(a)) return 0; + } else if (type == 3) { + return 0; + } else { + if (type == 1) { + // use fixed code lengths + if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0; + if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0; + } else { + if (!stbi__compute_huffman_codes(a)) return 0; + } + if (!stbi__parse_huffman_block(a)) return 0; + } + } while (!final); + return 1; +} + +static int stbi__do_zlib(stbi__zbuf *a, char *obuf, int olen, int exp, int parse_header) +{ + a->zout_start = obuf; + a->zout = obuf; + a->zout_end = obuf + olen; + a->z_expandable = exp; + + return stbi__parse_zlib(a, parse_header); +} + +STBIDEF char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if (stbi__do_zlib(&a, p, initial_size, 1, 1)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) +{ + return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); +} + +STBIDEF char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer + len; + if (stbi__do_zlib(&a, p, initial_size, 1, parse_header)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) +{ + stbi__zbuf a; + a.zbuffer = (stbi_uc *) ibuffer; + a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + if (stbi__do_zlib(&a, obuffer, olen, 0, 1)) + return (int) (a.zout - a.zout_start); + else + return -1; +} + +STBIDEF char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) +{ + stbi__zbuf a; + char *p = (char *) stbi__malloc(16384); + if (p == NULL) return NULL; + a.zbuffer = (stbi_uc *) buffer; + a.zbuffer_end = (stbi_uc *) buffer+len; + if (stbi__do_zlib(&a, p, 16384, 1, 0)) { + if (outlen) *outlen = (int) (a.zout - a.zout_start); + return a.zout_start; + } else { + STBI_FREE(a.zout_start); + return NULL; + } +} + +STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) +{ + stbi__zbuf a; + a.zbuffer = (stbi_uc *) ibuffer; + a.zbuffer_end = (stbi_uc *) ibuffer + ilen; + if (stbi__do_zlib(&a, obuffer, olen, 0, 0)) + return (int) (a.zout - a.zout_start); + else + return -1; +} +#endif + +// public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 +// simple implementation +// - only 8-bit samples +// - no CRC checking +// - allocates lots of intermediate memory +// - avoids problem of streaming data between subsystems +// - avoids explicit window management +// performance +// - uses stb_zlib, a PD zlib implementation with fast huffman decoding + +#ifndef STBI_NO_PNG +typedef struct +{ + stbi__uint32 length; + stbi__uint32 type; +} stbi__pngchunk; + +static stbi__pngchunk stbi__get_chunk_header(stbi__context *s) +{ + stbi__pngchunk c; + c.length = stbi__get32be(s); + c.type = stbi__get32be(s); + return c; +} + +static int stbi__check_png_header(stbi__context *s) +{ + static const stbi_uc png_sig[8] = { 137,80,78,71,13,10,26,10 }; + int i; + for (i=0; i < 8; ++i) + if (stbi__get8(s) != png_sig[i]) return stbi__err("bad png sig","Not a PNG"); + return 1; +} + +typedef struct +{ + stbi__context *s; + stbi_uc *idata, *expanded, *out; + int depth; +} stbi__png; + + +enum { + STBI__F_none=0, + STBI__F_sub=1, + STBI__F_up=2, + STBI__F_avg=3, + STBI__F_paeth=4, + // synthetic filters used for first scanline to avoid needing a dummy row of 0s + STBI__F_avg_first, + STBI__F_paeth_first +}; + +static stbi_uc first_row_filter[5] = +{ + STBI__F_none, + STBI__F_sub, + STBI__F_none, + STBI__F_avg_first, + STBI__F_paeth_first +}; + +static int stbi__paeth(int a, int b, int c) +{ + int p = a + b - c; + int pa = abs(p-a); + int pb = abs(p-b); + int pc = abs(p-c); + if (pa <= pb && pa <= pc) return a; + if (pb <= pc) return b; + return c; +} + +static const stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x01 }; + +// create the png data from post-deflated data +static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color) +{ + int bytes = (depth == 16? 2 : 1); + stbi__context *s = a->s; + stbi__uint32 i,j,stride = x*out_n*bytes; + stbi__uint32 img_len, img_width_bytes; + int k; + int img_n = s->img_n; // copy it into a local for later + + int output_bytes = out_n*bytes; + int filter_bytes = img_n*bytes; + int width = x; + + STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1); + a->out = (stbi_uc *) stbi__malloc_mad3(x, y, output_bytes, 0); // extra bytes to write off the end into + if (!a->out) return stbi__err("outofmem", "Out of memory"); + + if (!stbi__mad3sizes_valid(img_n, x, depth, 7)) return stbi__err("too large", "Corrupt PNG"); + img_width_bytes = (((img_n * x * depth) + 7) >> 3); + img_len = (img_width_bytes + 1) * y; + + // we used to check for exact match between raw_len and img_len on non-interlaced PNGs, + // but issue #276 reported a PNG in the wild that had extra data at the end (all zeros), + // so just check for raw_len < img_len always. + if (raw_len < img_len) return stbi__err("not enough pixels","Corrupt PNG"); + + for (j=0; j < y; ++j) { + stbi_uc *cur = a->out + stride*j; + stbi_uc *prior; + int filter = *raw++; + + if (filter > 4) + return stbi__err("invalid filter","Corrupt PNG"); + + if (depth < 8) { + STBI_ASSERT(img_width_bytes <= x); + cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place + filter_bytes = 1; + width = img_width_bytes; + } + prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above + + // if first row, use special filter that doesn't sample previous row + if (j == 0) filter = first_row_filter[filter]; + + // handle first byte explicitly + for (k=0; k < filter_bytes; ++k) { + switch (filter) { + case STBI__F_none : cur[k] = raw[k]; break; + case STBI__F_sub : cur[k] = raw[k]; break; + case STBI__F_up : cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break; + case STBI__F_avg : cur[k] = STBI__BYTECAST(raw[k] + (prior[k]>>1)); break; + case STBI__F_paeth : cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(0,prior[k],0)); break; + case STBI__F_avg_first : cur[k] = raw[k]; break; + case STBI__F_paeth_first: cur[k] = raw[k]; break; + } + } + + if (depth == 8) { + if (img_n != out_n) + cur[img_n] = 255; // first pixel + raw += img_n; + cur += out_n; + prior += out_n; + } else if (depth == 16) { + if (img_n != out_n) { + cur[filter_bytes] = 255; // first pixel top byte + cur[filter_bytes+1] = 255; // first pixel bottom byte + } + raw += filter_bytes; + cur += output_bytes; + prior += output_bytes; + } else { + raw += 1; + cur += 1; + prior += 1; + } + + // this is a little gross, so that we don't switch per-pixel or per-component + if (depth < 8 || img_n == out_n) { + int nk = (width - 1)*filter_bytes; + #define STBI__CASE(f) \ + case f: \ + for (k=0; k < nk; ++k) + switch (filter) { + // "none" filter turns into a memcpy here; make that explicit. + case STBI__F_none: memcpy(cur, raw, nk); break; + STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k-filter_bytes]); } break; + STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; + STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-filter_bytes])>>1)); } break; + STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],prior[k],prior[k-filter_bytes])); } break; + STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k-filter_bytes] >> 1)); } break; + STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-filter_bytes],0,0)); } break; + } + #undef STBI__CASE + raw += nk; + } else { + STBI_ASSERT(img_n+1 == out_n); + #define STBI__CASE(f) \ + case f: \ + for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \ + for (k=0; k < filter_bytes; ++k) + switch (filter) { + STBI__CASE(STBI__F_none) { cur[k] = raw[k]; } break; + STBI__CASE(STBI__F_sub) { cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); } break; + STBI__CASE(STBI__F_up) { cur[k] = STBI__BYTECAST(raw[k] + prior[k]); } break; + STBI__CASE(STBI__F_avg) { cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); } break; + STBI__CASE(STBI__F_paeth) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); } break; + STBI__CASE(STBI__F_avg_first) { cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); } break; + STBI__CASE(STBI__F_paeth_first) { cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); } break; + } + #undef STBI__CASE + + // the loop above sets the high byte of the pixels' alpha, but for + // 16 bit png files we also need the low byte set. we'll do that here. + if (depth == 16) { + cur = a->out + stride*j; // start at the beginning of the row again + for (i=0; i < x; ++i,cur+=output_bytes) { + cur[filter_bytes+1] = 255; + } + } + } + } + + // we make a separate pass to expand bits to pixels; for performance, + // this could run two scanlines behind the above code, so it won't + // intefere with filtering but will still be in the cache. + if (depth < 8) { + for (j=0; j < y; ++j) { + stbi_uc *cur = a->out + stride*j; + stbi_uc *in = a->out + stride*j + x*out_n - img_width_bytes; + // unpack 1/2/4-bit into a 8-bit buffer. allows us to keep the common 8-bit path optimal at minimal cost for 1/2/4-bit + // png guarante byte alignment, if width is not multiple of 8/4/2 we'll decode dummy trailing data that will be skipped in the later loop + stbi_uc scale = (color == 0) ? stbi__depth_scale_table[depth] : 1; // scale grayscale values to 0..255 range + + // note that the final byte might overshoot and write more data than desired. + // we can allocate enough data that this never writes out of memory, but it + // could also overwrite the next scanline. can it overwrite non-empty data + // on the next scanline? yes, consider 1-pixel-wide scanlines with 1-bit-per-pixel. + // so we need to explicitly clamp the final ones + + if (depth == 4) { + for (k=x*img_n; k >= 2; k-=2, ++in) { + *cur++ = scale * ((*in >> 4) ); + *cur++ = scale * ((*in ) & 0x0f); + } + if (k > 0) *cur++ = scale * ((*in >> 4) ); + } else if (depth == 2) { + for (k=x*img_n; k >= 4; k-=4, ++in) { + *cur++ = scale * ((*in >> 6) ); + *cur++ = scale * ((*in >> 4) & 0x03); + *cur++ = scale * ((*in >> 2) & 0x03); + *cur++ = scale * ((*in ) & 0x03); + } + if (k > 0) *cur++ = scale * ((*in >> 6) ); + if (k > 1) *cur++ = scale * ((*in >> 4) & 0x03); + if (k > 2) *cur++ = scale * ((*in >> 2) & 0x03); + } else if (depth == 1) { + for (k=x*img_n; k >= 8; k-=8, ++in) { + *cur++ = scale * ((*in >> 7) ); + *cur++ = scale * ((*in >> 6) & 0x01); + *cur++ = scale * ((*in >> 5) & 0x01); + *cur++ = scale * ((*in >> 4) & 0x01); + *cur++ = scale * ((*in >> 3) & 0x01); + *cur++ = scale * ((*in >> 2) & 0x01); + *cur++ = scale * ((*in >> 1) & 0x01); + *cur++ = scale * ((*in ) & 0x01); + } + if (k > 0) *cur++ = scale * ((*in >> 7) ); + if (k > 1) *cur++ = scale * ((*in >> 6) & 0x01); + if (k > 2) *cur++ = scale * ((*in >> 5) & 0x01); + if (k > 3) *cur++ = scale * ((*in >> 4) & 0x01); + if (k > 4) *cur++ = scale * ((*in >> 3) & 0x01); + if (k > 5) *cur++ = scale * ((*in >> 2) & 0x01); + if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01); + } + if (img_n != out_n) { + int q; + // insert alpha = 255 + cur = a->out + stride*j; + if (img_n == 1) { + for (q=x-1; q >= 0; --q) { + cur[q*2+1] = 255; + cur[q*2+0] = cur[q]; + } + } else { + STBI_ASSERT(img_n == 3); + for (q=x-1; q >= 0; --q) { + cur[q*4+3] = 255; + cur[q*4+2] = cur[q*3+2]; + cur[q*4+1] = cur[q*3+1]; + cur[q*4+0] = cur[q*3+0]; + } + } + } + } + } else if (depth == 16) { + // force the image data from big-endian to platform-native. + // this is done in a separate pass due to the decoding relying + // on the data being untouched, but could probably be done + // per-line during decode if care is taken. + stbi_uc *cur = a->out; + stbi__uint16 *cur16 = (stbi__uint16*)cur; + + for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) { + *cur16 = (cur[0] << 8) | cur[1]; + } + } + + return 1; +} + +static int stbi__create_png_image(stbi__png *a, stbi_uc *image_data, stbi__uint32 image_data_len, int out_n, int depth, int color, int interlaced) +{ + int bytes = (depth == 16 ? 2 : 1); + int out_bytes = out_n * bytes; + stbi_uc *final; + int p; + if (!interlaced) + return stbi__create_png_image_raw(a, image_data, image_data_len, out_n, a->s->img_x, a->s->img_y, depth, color); + + // de-interlacing + final = (stbi_uc *) stbi__malloc_mad3(a->s->img_x, a->s->img_y, out_bytes, 0); + for (p=0; p < 7; ++p) { + int xorig[] = { 0,4,0,2,0,1,0 }; + int yorig[] = { 0,0,4,0,2,0,1 }; + int xspc[] = { 8,8,4,4,2,2,1 }; + int yspc[] = { 8,8,8,4,4,2,2 }; + int i,j,x,y; + // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 + x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p]; + y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p]; + if (x && y) { + stbi__uint32 img_len = ((((a->s->img_n * x * depth) + 7) >> 3) + 1) * y; + if (!stbi__create_png_image_raw(a, image_data, image_data_len, out_n, x, y, depth, color)) { + STBI_FREE(final); + return 0; + } + for (j=0; j < y; ++j) { + for (i=0; i < x; ++i) { + int out_y = j*yspc[p]+yorig[p]; + int out_x = i*xspc[p]+xorig[p]; + memcpy(final + out_y*a->s->img_x*out_bytes + out_x*out_bytes, + a->out + (j*x+i)*out_bytes, out_bytes); + } + } + STBI_FREE(a->out); + image_data += img_len; + image_data_len -= img_len; + } + } + a->out = final; + + return 1; +} + +static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi_uc *p = z->out; + + // compute color-based transparency, assuming we've + // already got 255 as the alpha value in the output + STBI_ASSERT(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i=0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 255); + p += 2; + } + } else { + for (i=0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi__uint16 *p = (stbi__uint16*) z->out; + + // compute color-based transparency, assuming we've + // already got 65535 as the alpha value in the output + STBI_ASSERT(out_n == 2 || out_n == 4); + + if (out_n == 2) { + for (i = 0; i < pixel_count; ++i) { + p[1] = (p[0] == tc[0] ? 0 : 65535); + p += 2; + } + } else { + for (i = 0; i < pixel_count; ++i) { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; +} + +static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n) +{ + stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y; + stbi_uc *p, *temp_out, *orig = a->out; + + p = (stbi_uc *) stbi__malloc_mad2(pixel_count, pal_img_n, 0); + if (p == NULL) return stbi__err("outofmem", "Out of memory"); + + // between here and free(out) below, exitting would leak + temp_out = p; + + if (pal_img_n == 3) { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p += 3; + } + } else { + for (i=0; i < pixel_count; ++i) { + int n = orig[i]*4; + p[0] = palette[n ]; + p[1] = palette[n+1]; + p[2] = palette[n+2]; + p[3] = palette[n+3]; + p += 4; + } + } + STBI_FREE(a->out); + a->out = temp_out; + + STBI_NOTUSED(len); + + return 1; +} + +static int stbi__unpremultiply_on_load = 0; +static int stbi__de_iphone_flag = 0; + +STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) +{ + stbi__unpremultiply_on_load = flag_true_if_should_unpremultiply; +} + +STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) +{ + stbi__de_iphone_flag = flag_true_if_should_convert; +} + +static void stbi__de_iphone(stbi__png *z) +{ + stbi__context *s = z->s; + stbi__uint32 i, pixel_count = s->img_x * s->img_y; + stbi_uc *p = z->out; + + if (s->img_out_n == 3) { // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + stbi_uc t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 3; + } + } else { + STBI_ASSERT(s->img_out_n == 4); + if (stbi__unpremultiply_on_load) { + // convert bgr to rgb and unpremultiply + for (i=0; i < pixel_count; ++i) { + stbi_uc a = p[3]; + stbi_uc t = p[0]; + if (a) { + stbi_uc half = a / 2; + p[0] = (p[2] * 255 + half) / a; + p[1] = (p[1] * 255 + half) / a; + p[2] = ( t * 255 + half) / a; + } else { + p[0] = p[2]; + p[2] = t; + } + p += 4; + } + } else { + // convert bgr to rgb + for (i=0; i < pixel_count; ++i) { + stbi_uc t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 4; + } + } + } +} + +#define STBI__PNG_TYPE(a,b,c,d) (((unsigned) (a) << 24) + ((unsigned) (b) << 16) + ((unsigned) (c) << 8) + (unsigned) (d)) + +static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp) +{ + stbi_uc palette[1024], pal_img_n=0; + stbi_uc has_trans=0, tc[3]={0}; + stbi__uint16 tc16[3]; + stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0; + int first=1,k,interlace=0, color=0, is_iphone=0; + stbi__context *s = z->s; + + z->expanded = NULL; + z->idata = NULL; + z->out = NULL; + + if (!stbi__check_png_header(s)) return 0; + + if (scan == STBI__SCAN_type) return 1; + + for (;;) { + stbi__pngchunk c = stbi__get_chunk_header(s); + switch (c.type) { + case STBI__PNG_TYPE('C','g','B','I'): + is_iphone = 1; + stbi__skip(s, c.length); + break; + case STBI__PNG_TYPE('I','H','D','R'): { + int comp,filter; + if (!first) return stbi__err("multiple IHDR","Corrupt PNG"); + first = 0; + if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG"); + s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); + s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)"); + z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only"); + color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG"); + if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG"); + if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG"); + comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG"); + filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG"); + interlace = stbi__get8(s); if (interlace>1) return stbi__err("bad interlace method","Corrupt PNG"); + if (!s->img_x || !s->img_y) return stbi__err("0-pixel image","Corrupt PNG"); + if (!pal_img_n) { + s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode"); + if (scan == STBI__SCAN_header) return 1; + } else { + // if paletted, then pal_n is our final components, and + // img_n is # components to decompress/filter. + s->img_n = 1; + if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG"); + // if SCAN_header, have to scan to see if we have a tRNS + } + break; + } + + case STBI__PNG_TYPE('P','L','T','E'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (c.length > 256*3) return stbi__err("invalid PLTE","Corrupt PNG"); + pal_len = c.length / 3; + if (pal_len * 3 != c.length) return stbi__err("invalid PLTE","Corrupt PNG"); + for (i=0; i < pal_len; ++i) { + palette[i*4+0] = stbi__get8(s); + palette[i*4+1] = stbi__get8(s); + palette[i*4+2] = stbi__get8(s); + palette[i*4+3] = 255; + } + break; + } + + case STBI__PNG_TYPE('t','R','N','S'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (z->idata) return stbi__err("tRNS after IDAT","Corrupt PNG"); + if (pal_img_n) { + if (scan == STBI__SCAN_header) { s->img_n = 4; return 1; } + if (pal_len == 0) return stbi__err("tRNS before PLTE","Corrupt PNG"); + if (c.length > pal_len) return stbi__err("bad tRNS len","Corrupt PNG"); + pal_img_n = 4; + for (i=0; i < c.length; ++i) + palette[i*4+3] = stbi__get8(s); + } else { + if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG"); + if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG"); + has_trans = 1; + if (z->depth == 16) { + for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is + } else { + for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger + } + } + break; + } + + case STBI__PNG_TYPE('I','D','A','T'): { + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG"); + if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; } + if ((int)(ioff + c.length) < (int)ioff) return 0; + if (ioff + c.length > idata_limit) { + stbi__uint32 idata_limit_old = idata_limit; + stbi_uc *p; + if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; + while (ioff + c.length > idata_limit) + idata_limit *= 2; + STBI_NOTUSED(idata_limit_old); + p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory"); + z->idata = p; + } + if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG"); + ioff += c.length; + break; + } + + case STBI__PNG_TYPE('I','E','N','D'): { + stbi__uint32 raw_len, bpl; + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if (scan != STBI__SCAN_load) return 1; + if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG"); + // initial guess for decoded data size to avoid unnecessary reallocs + bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component + raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */; + z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone); + if (z->expanded == NULL) return 0; // zlib should set error + STBI_FREE(z->idata); z->idata = NULL; + if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) + s->img_out_n = s->img_n+1; + else + s->img_out_n = s->img_n; + if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0; + if (has_trans) { + if (z->depth == 16) { + if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0; + } else { + if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0; + } + } + if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2) + stbi__de_iphone(z); + if (pal_img_n) { + // pal_img_n == 3 or 4 + s->img_n = pal_img_n; // record the actual colors we had + s->img_out_n = pal_img_n; + if (req_comp >= 3) s->img_out_n = req_comp; + if (!stbi__expand_png_palette(z, palette, pal_len, s->img_out_n)) + return 0; + } else if (has_trans) { + // non-paletted image with tRNS -> source image has (constant) alpha + ++s->img_n; + } + STBI_FREE(z->expanded); z->expanded = NULL; + // end of PNG chunk, read and skip CRC + stbi__get32be(s); + return 1; + } + + default: + // if critical, fail + if (first) return stbi__err("first not IHDR", "Corrupt PNG"); + if ((c.type & (1 << 29)) == 0) { + #ifndef STBI_NO_FAILURE_STRINGS + // not threadsafe + static char invalid_chunk[] = "XXXX PNG chunk not known"; + invalid_chunk[0] = STBI__BYTECAST(c.type >> 24); + invalid_chunk[1] = STBI__BYTECAST(c.type >> 16); + invalid_chunk[2] = STBI__BYTECAST(c.type >> 8); + invalid_chunk[3] = STBI__BYTECAST(c.type >> 0); + #endif + return stbi__err(invalid_chunk, "PNG not supported: unknown PNG chunk type"); + } + stbi__skip(s, c.length); + break; + } + // end of PNG chunk, read and skip CRC + stbi__get32be(s); + } +} + +static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, stbi__result_info *ri) +{ + void *result=NULL; + if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error"); + if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) { + if (p->depth < 8) + ri->bits_per_channel = 8; + else + ri->bits_per_channel = p->depth; + result = p->out; + p->out = NULL; + if (req_comp && req_comp != p->s->img_out_n) { + if (ri->bits_per_channel == 8) + result = stbi__convert_format((unsigned char *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + else + result = stbi__convert_format16((stbi__uint16 *) result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + p->s->img_out_n = req_comp; + if (result == NULL) return result; + } + *x = p->s->img_x; + *y = p->s->img_y; + if (n) *n = p->s->img_n; + } + STBI_FREE(p->out); p->out = NULL; + STBI_FREE(p->expanded); p->expanded = NULL; + STBI_FREE(p->idata); p->idata = NULL; + + return result; +} + +static void *stbi__png_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi__png p; + p.s = s; + return stbi__do_png(&p, x,y,comp,req_comp, ri); +} + +static int stbi__png_test(stbi__context *s) +{ + int r; + r = stbi__check_png_header(s); + stbi__rewind(s); + return r; +} + +static int stbi__png_info_raw(stbi__png *p, int *x, int *y, int *comp) +{ + if (!stbi__parse_png_file(p, STBI__SCAN_header, 0)) { + stbi__rewind( p->s ); + return 0; + } + if (x) *x = p->s->img_x; + if (y) *y = p->s->img_y; + if (comp) *comp = p->s->img_n; + return 1; +} + +static int stbi__png_info(stbi__context *s, int *x, int *y, int *comp) +{ + stbi__png p; + p.s = s; + return stbi__png_info_raw(&p, x, y, comp); +} + +static int stbi__png_is16(stbi__context *s) +{ + stbi__png p; + p.s = s; + if (!stbi__png_info_raw(&p, NULL, NULL, NULL)) + return 0; + if (p.depth != 16) { + stbi__rewind(p.s); + return 0; + } + return 1; +} +#endif + +// Microsoft/Windows BMP image + +#ifndef STBI_NO_BMP +static int stbi__bmp_test_raw(stbi__context *s) +{ + int r; + int sz; + if (stbi__get8(s) != 'B') return 0; + if (stbi__get8(s) != 'M') return 0; + stbi__get32le(s); // discard filesize + stbi__get16le(s); // discard reserved + stbi__get16le(s); // discard reserved + stbi__get32le(s); // discard data offset + sz = stbi__get32le(s); + r = (sz == 12 || sz == 40 || sz == 56 || sz == 108 || sz == 124); + return r; +} + +static int stbi__bmp_test(stbi__context *s) +{ + int r = stbi__bmp_test_raw(s); + stbi__rewind(s); + return r; +} + + +// returns 0..31 for the highest set bit +static int stbi__high_bit(unsigned int z) +{ + int n=0; + if (z == 0) return -1; + if (z >= 0x10000) { n += 16; z >>= 16; } + if (z >= 0x00100) { n += 8; z >>= 8; } + if (z >= 0x00010) { n += 4; z >>= 4; } + if (z >= 0x00004) { n += 2; z >>= 2; } + if (z >= 0x00002) { n += 1;/* >>= 1;*/ } + return n; +} + +static int stbi__bitcount(unsigned int a) +{ + a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 + a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits + a = (a + (a >> 8)); // max 16 per 8 bits + a = (a + (a >> 16)); // max 32 per 8 bits + return a & 0xff; +} + +// extract an arbitrarily-aligned N-bit value (N=bits) +// from v, and then make it 8-bits long and fractionally +// extend it to full full range. +static int stbi__shiftsigned(unsigned int v, int shift, int bits) +{ + static unsigned int mul_table[9] = { + 0, + 0xff/*0b11111111*/, 0x55/*0b01010101*/, 0x49/*0b01001001*/, 0x11/*0b00010001*/, + 0x21/*0b00100001*/, 0x41/*0b01000001*/, 0x81/*0b10000001*/, 0x01/*0b00000001*/, + }; + static unsigned int shift_table[9] = { + 0, 0,0,1,0,2,4,6,0, + }; + if (shift < 0) + v <<= -shift; + else + v >>= shift; + STBI_ASSERT(v < 256); + v >>= (8-bits); + STBI_ASSERT(bits >= 0 && bits <= 8); + return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits]; +} + +typedef struct +{ + int bpp, offset, hsz; + unsigned int mr,mg,mb,ma, all_a; + int extra_read; +} stbi__bmp_data; + +static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info) +{ + int hsz; + if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP"); + stbi__get32le(s); // discard filesize + stbi__get16le(s); // discard reserved + stbi__get16le(s); // discard reserved + info->offset = stbi__get32le(s); + info->hsz = hsz = stbi__get32le(s); + info->mr = info->mg = info->mb = info->ma = 0; + info->extra_read = 14; + + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown"); + if (hsz == 12) { + s->img_x = stbi__get16le(s); + s->img_y = stbi__get16le(s); + } else { + s->img_x = stbi__get32le(s); + s->img_y = stbi__get32le(s); + } + if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP"); + info->bpp = stbi__get16le(s); + if (hsz != 12) { + int compress = stbi__get32le(s); + if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE"); + stbi__get32le(s); // discard sizeof + stbi__get32le(s); // discard hres + stbi__get32le(s); // discard vres + stbi__get32le(s); // discard colorsused + stbi__get32le(s); // discard max important + if (hsz == 40 || hsz == 56) { + if (hsz == 56) { + stbi__get32le(s); + stbi__get32le(s); + stbi__get32le(s); + stbi__get32le(s); + } + if (info->bpp == 16 || info->bpp == 32) { + if (compress == 0) { + if (info->bpp == 32) { + info->mr = 0xffu << 16; + info->mg = 0xffu << 8; + info->mb = 0xffu << 0; + info->ma = 0xffu << 24; + info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0 + } else { + info->mr = 31u << 10; + info->mg = 31u << 5; + info->mb = 31u << 0; + } + } else if (compress == 3) { + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + info->extra_read += 12; + // not documented, but generated by photoshop and handled by mspaint + if (info->mr == info->mg && info->mg == info->mb) { + // ?!?!? + return stbi__errpuc("bad BMP", "bad BMP"); + } + } else + return stbi__errpuc("bad BMP", "bad BMP"); + } + } else { + int i; + if (hsz != 108 && hsz != 124) + return stbi__errpuc("bad BMP", "bad BMP"); + info->mr = stbi__get32le(s); + info->mg = stbi__get32le(s); + info->mb = stbi__get32le(s); + info->ma = stbi__get32le(s); + stbi__get32le(s); // discard color space + for (i=0; i < 12; ++i) + stbi__get32le(s); // discard color space parameters + if (hsz == 124) { + stbi__get32le(s); // discard rendering intent + stbi__get32le(s); // discard offset of profile data + stbi__get32le(s); // discard size of profile data + stbi__get32le(s); // discard reserved + } + } + } + return (void *) 1; +} + + +static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi_uc *out; + unsigned int mr=0,mg=0,mb=0,ma=0, all_a; + stbi_uc pal[256][4]; + int psize=0,i,j,width; + int flip_vertically, pad, target; + stbi__bmp_data info; + STBI_NOTUSED(ri); + + info.all_a = 255; + if (stbi__bmp_parse_header(s, &info) == NULL) + return NULL; // error code already set + + flip_vertically = ((int) s->img_y) > 0; + s->img_y = abs((int) s->img_y); + + mr = info.mr; + mg = info.mg; + mb = info.mb; + ma = info.ma; + all_a = info.all_a; + + if (info.hsz == 12) { + if (info.bpp < 24) + psize = (info.offset - info.extra_read - 24) / 3; + } else { + if (info.bpp < 16) + psize = (info.offset - info.extra_read - info.hsz) >> 2; + } + if (psize == 0) { + STBI_ASSERT(info.offset == (s->img_buffer - s->buffer_start)); + } + + if (info.bpp == 24 && ma == 0xff000000) + s->img_n = 3; + else + s->img_n = ma ? 4 : 3; + if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 + target = req_comp; + else + target = s->img_n; // if they want monochrome, we'll post-convert + + // sanity-check size + if (!stbi__mad3sizes_valid(target, s->img_x, s->img_y, 0)) + return stbi__errpuc("too large", "Corrupt BMP"); + + out = (stbi_uc *) stbi__malloc_mad3(target, s->img_x, s->img_y, 0); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + if (info.bpp < 16) { + int z=0; + if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); } + for (i=0; i < psize; ++i) { + pal[i][2] = stbi__get8(s); + pal[i][1] = stbi__get8(s); + pal[i][0] = stbi__get8(s); + if (info.hsz != 12) stbi__get8(s); + pal[i][3] = 255; + } + stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); + if (info.bpp == 1) width = (s->img_x + 7) >> 3; + else if (info.bpp == 4) width = (s->img_x + 1) >> 1; + else if (info.bpp == 8) width = s->img_x; + else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); } + pad = (-width)&3; + if (info.bpp == 1) { + for (j=0; j < (int) s->img_y; ++j) { + int bit_offset = 7, v = stbi__get8(s); + for (i=0; i < (int) s->img_x; ++i) { + int color = (v>>bit_offset)&0x1; + out[z++] = pal[color][0]; + out[z++] = pal[color][1]; + out[z++] = pal[color][2]; + if (target == 4) out[z++] = 255; + if (i+1 == (int) s->img_x) break; + if((--bit_offset) < 0) { + bit_offset = 7; + v = stbi__get8(s); + } + } + stbi__skip(s, pad); + } + } else { + for (j=0; j < (int) s->img_y; ++j) { + for (i=0; i < (int) s->img_x; i += 2) { + int v=stbi__get8(s),v2=0; + if (info.bpp == 4) { + v2 = v & 15; + v >>= 4; + } + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + if (i+1 == (int) s->img_x) break; + v = (info.bpp == 8) ? stbi__get8(s) : v2; + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + } + stbi__skip(s, pad); + } + } + } else { + int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; + int z = 0; + int easy=0; + stbi__skip(s, info.offset - info.extra_read - info.hsz); + if (info.bpp == 24) width = 3 * s->img_x; + else if (info.bpp == 16) width = 2*s->img_x; + else /* bpp = 32 and pad = 0 */ width=0; + pad = (-width) & 3; + if (info.bpp == 24) { + easy = 1; + } else if (info.bpp == 32) { + if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) + easy = 2; + } + if (!easy) { + if (!mr || !mg || !mb) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); } + // right shift amt to put high bit in position #7 + rshift = stbi__high_bit(mr)-7; rcount = stbi__bitcount(mr); + gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg); + bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb); + ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma); + } + for (j=0; j < (int) s->img_y; ++j) { + if (easy) { + for (i=0; i < (int) s->img_x; ++i) { + unsigned char a; + out[z+2] = stbi__get8(s); + out[z+1] = stbi__get8(s); + out[z+0] = stbi__get8(s); + z += 3; + a = (easy == 2 ? stbi__get8(s) : 255); + all_a |= a; + if (target == 4) out[z++] = a; + } + } else { + int bpp = info.bpp; + for (i=0; i < (int) s->img_x; ++i) { + stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s)); + unsigned int a; + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount)); + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount)); + out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount)); + a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255); + all_a |= a; + if (target == 4) out[z++] = STBI__BYTECAST(a); + } + } + stbi__skip(s, pad); + } + } + + // if alpha channel is all 0s, replace with all 255s + if (target == 4 && all_a == 0) + for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4) + out[i] = 255; + + if (flip_vertically) { + stbi_uc t; + for (j=0; j < (int) s->img_y>>1; ++j) { + stbi_uc *p1 = out + j *s->img_x*target; + stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; + for (i=0; i < (int) s->img_x*target; ++i) { + t = p1[i]; p1[i] = p2[i]; p2[i] = t; + } + } + } + + if (req_comp && req_comp != target) { + out = stbi__convert_format(out, target, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + + *x = s->img_x; + *y = s->img_y; + if (comp) *comp = s->img_n; + return out; +} +#endif + +// Targa Truevision - TGA +// by Jonathan Dummer +#ifndef STBI_NO_TGA +// returns STBI_rgb or whatever, 0 on error +static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16) +{ + // only RGB or RGBA (incl. 16bit) or grey allowed + if (is_rgb16) *is_rgb16 = 0; + switch(bits_per_pixel) { + case 8: return STBI_grey; + case 16: if(is_grey) return STBI_grey_alpha; + // fallthrough + case 15: if(is_rgb16) *is_rgb16 = 1; + return STBI_rgb; + case 24: // fallthrough + case 32: return bits_per_pixel/8; + default: return 0; + } +} + +static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp) +{ + int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp; + int sz, tga_colormap_type; + stbi__get8(s); // discard Offset + tga_colormap_type = stbi__get8(s); // colormap type + if( tga_colormap_type > 1 ) { + stbi__rewind(s); + return 0; // only RGB or indexed allowed + } + tga_image_type = stbi__get8(s); // image type + if ( tga_colormap_type == 1 ) { // colormapped (paletted) image + if (tga_image_type != 1 && tga_image_type != 9) { + stbi__rewind(s); + return 0; + } + stbi__skip(s,4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) { + stbi__rewind(s); + return 0; + } + stbi__skip(s,4); // skip image x and y origin + tga_colormap_bpp = sz; + } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE + if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) { + stbi__rewind(s); + return 0; // only RGB or grey allowed, +/- RLE + } + stbi__skip(s,9); // skip colormap specification and image x/y origin + tga_colormap_bpp = 0; + } + tga_w = stbi__get16le(s); + if( tga_w < 1 ) { + stbi__rewind(s); + return 0; // test width + } + tga_h = stbi__get16le(s); + if( tga_h < 1 ) { + stbi__rewind(s); + return 0; // test height + } + tga_bits_per_pixel = stbi__get8(s); // bits per pixel + stbi__get8(s); // ignore alpha bits + if (tga_colormap_bpp != 0) { + if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) { + // when using a colormap, tga_bits_per_pixel is the size of the indexes + // I don't think anything but 8 or 16bit indexes makes sense + stbi__rewind(s); + return 0; + } + tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL); + } else { + tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL); + } + if(!tga_comp) { + stbi__rewind(s); + return 0; + } + if (x) *x = tga_w; + if (y) *y = tga_h; + if (comp) *comp = tga_comp; + return 1; // seems to have passed everything +} + +static int stbi__tga_test(stbi__context *s) +{ + int res = 0; + int sz, tga_color_type; + stbi__get8(s); // discard Offset + tga_color_type = stbi__get8(s); // color type + if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed + sz = stbi__get8(s); // image type + if ( tga_color_type == 1 ) { // colormapped (paletted) image + if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9 + stbi__skip(s,4); // skip index of first colormap entry and number of entries + sz = stbi__get8(s); // check bits per palette color entry + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + stbi__skip(s,4); // skip image x and y origin + } else { // "normal" image w/o colormap + if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE + stbi__skip(s,9); // skip colormap specification and image x/y origin + } + if ( stbi__get16le(s) < 1 ) goto errorEnd; // test width + if ( stbi__get16le(s) < 1 ) goto errorEnd; // test height + sz = stbi__get8(s); // bits per pixel + if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index + if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd; + + res = 1; // if we got this far, everything's good and we can return 1 instead of 0 + +errorEnd: + stbi__rewind(s); + return res; +} + +// read 16bit value and convert to 24bit RGB +static void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out) +{ + stbi__uint16 px = (stbi__uint16)stbi__get16le(s); + stbi__uint16 fiveBitMask = 31; + // we have 3 channels with 5bits each + int r = (px >> 10) & fiveBitMask; + int g = (px >> 5) & fiveBitMask; + int b = px & fiveBitMask; + // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later + out[0] = (stbi_uc)((r * 255)/31); + out[1] = (stbi_uc)((g * 255)/31); + out[2] = (stbi_uc)((b * 255)/31); + + // some people claim that the most significant bit might be used for alpha + // (possibly if an alpha-bit is set in the "image descriptor byte") + // but that only made 16bit test images completely translucent.. + // so let's treat all 15 and 16bit TGAs as RGB with no alpha. +} + +static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + // read in the TGA header stuff + int tga_offset = stbi__get8(s); + int tga_indexed = stbi__get8(s); + int tga_image_type = stbi__get8(s); + int tga_is_RLE = 0; + int tga_palette_start = stbi__get16le(s); + int tga_palette_len = stbi__get16le(s); + int tga_palette_bits = stbi__get8(s); + int tga_x_origin = stbi__get16le(s); + int tga_y_origin = stbi__get16le(s); + int tga_width = stbi__get16le(s); + int tga_height = stbi__get16le(s); + int tga_bits_per_pixel = stbi__get8(s); + int tga_comp, tga_rgb16=0; + int tga_inverted = stbi__get8(s); + // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?) + // image data + unsigned char *tga_data; + unsigned char *tga_palette = NULL; + int i, j; + unsigned char raw_data[4] = {0}; + int RLE_count = 0; + int RLE_repeating = 0; + int read_next_pixel = 1; + STBI_NOTUSED(ri); + STBI_NOTUSED(tga_x_origin); // @TODO + STBI_NOTUSED(tga_y_origin); // @TODO + + // do a tiny bit of precessing + if ( tga_image_type >= 8 ) + { + tga_image_type -= 8; + tga_is_RLE = 1; + } + tga_inverted = 1 - ((tga_inverted >> 5) & 1); + + // If I'm paletted, then I'll use the number of bits from the palette + if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16); + else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16); + + if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency + return stbi__errpuc("bad format", "Can't find out TGA pixelformat"); + + // tga info + *x = tga_width; + *y = tga_height; + if (comp) *comp = tga_comp; + + if (!stbi__mad3sizes_valid(tga_width, tga_height, tga_comp, 0)) + return stbi__errpuc("too large", "Corrupt TGA"); + + tga_data = (unsigned char*)stbi__malloc_mad3(tga_width, tga_height, tga_comp, 0); + if (!tga_data) return stbi__errpuc("outofmem", "Out of memory"); + + // skip to the data's starting position (offset usually = 0) + stbi__skip(s, tga_offset ); + + if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) { + for (i=0; i < tga_height; ++i) { + int row = tga_inverted ? tga_height -i - 1 : i; + stbi_uc *tga_row = tga_data + row*tga_width*tga_comp; + stbi__getn(s, tga_row, tga_width * tga_comp); + } + } else { + // do I need to load a palette? + if ( tga_indexed) + { + // any data to skip? (offset usually = 0) + stbi__skip(s, tga_palette_start ); + // load the palette + tga_palette = (unsigned char*)stbi__malloc_mad2(tga_palette_len, tga_comp, 0); + if (!tga_palette) { + STBI_FREE(tga_data); + return stbi__errpuc("outofmem", "Out of memory"); + } + if (tga_rgb16) { + stbi_uc *pal_entry = tga_palette; + STBI_ASSERT(tga_comp == STBI_rgb); + for (i=0; i < tga_palette_len; ++i) { + stbi__tga_read_rgb16(s, pal_entry); + pal_entry += tga_comp; + } + } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) { + STBI_FREE(tga_data); + STBI_FREE(tga_palette); + return stbi__errpuc("bad palette", "Corrupt TGA"); + } + } + // load the data + for (i=0; i < tga_width * tga_height; ++i) + { + // if I'm in RLE mode, do I need to get a RLE stbi__pngchunk? + if ( tga_is_RLE ) + { + if ( RLE_count == 0 ) + { + // yep, get the next byte as a RLE command + int RLE_cmd = stbi__get8(s); + RLE_count = 1 + (RLE_cmd & 127); + RLE_repeating = RLE_cmd >> 7; + read_next_pixel = 1; + } else if ( !RLE_repeating ) + { + read_next_pixel = 1; + } + } else + { + read_next_pixel = 1; + } + // OK, if I need to read a pixel, do it now + if ( read_next_pixel ) + { + // load however much data we did have + if ( tga_indexed ) + { + // read in index, then perform the lookup + int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s); + if ( pal_idx >= tga_palette_len ) { + // invalid index + pal_idx = 0; + } + pal_idx *= tga_comp; + for (j = 0; j < tga_comp; ++j) { + raw_data[j] = tga_palette[pal_idx+j]; + } + } else if(tga_rgb16) { + STBI_ASSERT(tga_comp == STBI_rgb); + stbi__tga_read_rgb16(s, raw_data); + } else { + // read in the data raw + for (j = 0; j < tga_comp; ++j) { + raw_data[j] = stbi__get8(s); + } + } + // clear the reading flag for the next pixel + read_next_pixel = 0; + } // end of reading a pixel + + // copy data + for (j = 0; j < tga_comp; ++j) + tga_data[i*tga_comp+j] = raw_data[j]; + + // in case we're in RLE mode, keep counting down + --RLE_count; + } + // do I need to invert the image? + if ( tga_inverted ) + { + for (j = 0; j*2 < tga_height; ++j) + { + int index1 = j * tga_width * tga_comp; + int index2 = (tga_height - 1 - j) * tga_width * tga_comp; + for (i = tga_width * tga_comp; i > 0; --i) + { + unsigned char temp = tga_data[index1]; + tga_data[index1] = tga_data[index2]; + tga_data[index2] = temp; + ++index1; + ++index2; + } + } + } + // clear my palette, if I had one + if ( tga_palette != NULL ) + { + STBI_FREE( tga_palette ); + } + } + + // swap RGB - if the source data was RGB16, it already is in the right order + if (tga_comp >= 3 && !tga_rgb16) + { + unsigned char* tga_pixel = tga_data; + for (i=0; i < tga_width * tga_height; ++i) + { + unsigned char temp = tga_pixel[0]; + tga_pixel[0] = tga_pixel[2]; + tga_pixel[2] = temp; + tga_pixel += tga_comp; + } + } + + // convert to target component count + if (req_comp && req_comp != tga_comp) + tga_data = stbi__convert_format(tga_data, tga_comp, req_comp, tga_width, tga_height); + + // the things I do to get rid of an error message, and yet keep + // Microsoft's C compilers happy... [8^( + tga_palette_start = tga_palette_len = tga_palette_bits = + tga_x_origin = tga_y_origin = 0; + STBI_NOTUSED(tga_palette_start); + // OK, done + return tga_data; +} +#endif + +// ************************************************************************************************* +// Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB + +#ifndef STBI_NO_PSD +static int stbi__psd_test(stbi__context *s) +{ + int r = (stbi__get32be(s) == 0x38425053); + stbi__rewind(s); + return r; +} + +static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount) +{ + int count, nleft, len; + + count = 0; + while ((nleft = pixelCount - count) > 0) { + len = stbi__get8(s); + if (len == 128) { + // No-op. + } else if (len < 128) { + // Copy next len+1 bytes literally. + len++; + if (len > nleft) return 0; // corrupt data + count += len; + while (len) { + *p = stbi__get8(s); + p += 4; + len--; + } + } else if (len > 128) { + stbi_uc val; + // Next -len+1 bytes in the dest are replicated from next source byte. + // (Interpret len as a negative 8-bit int.) + len = 257 - len; + if (len > nleft) return 0; // corrupt data + val = stbi__get8(s); + count += len; + while (len) { + *p = val; + p += 4; + len--; + } + } + } + + return 1; +} + +static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri, int bpc) +{ + int pixelCount; + int channelCount, compression; + int channel, i; + int bitdepth; + int w,h; + stbi_uc *out; + STBI_NOTUSED(ri); + + // Check identifier + if (stbi__get32be(s) != 0x38425053) // "8BPS" + return stbi__errpuc("not PSD", "Corrupt PSD image"); + + // Check file type version. + if (stbi__get16be(s) != 1) + return stbi__errpuc("wrong version", "Unsupported version of PSD image"); + + // Skip 6 reserved bytes. + stbi__skip(s, 6 ); + + // Read the number of channels (R, G, B, A, etc). + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) + return stbi__errpuc("wrong channel count", "Unsupported number of channels in PSD image"); + + // Read the rows and columns of the image. + h = stbi__get32be(s); + w = stbi__get32be(s); + + // Make sure the depth is 8 bits. + bitdepth = stbi__get16be(s); + if (bitdepth != 8 && bitdepth != 16) + return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit"); + + // Make sure the color mode is RGB. + // Valid options are: + // 0: Bitmap + // 1: Grayscale + // 2: Indexed color + // 3: RGB color + // 4: CMYK color + // 7: Multichannel + // 8: Duotone + // 9: Lab color + if (stbi__get16be(s) != 3) + return stbi__errpuc("wrong color format", "PSD is not in RGB color format"); + + // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) + stbi__skip(s,stbi__get32be(s) ); + + // Skip the image resources. (resolution, pen tool paths, etc) + stbi__skip(s, stbi__get32be(s) ); + + // Skip the reserved data. + stbi__skip(s, stbi__get32be(s) ); + + // Find out if the data is compressed. + // Known values: + // 0: no compression + // 1: RLE compressed + compression = stbi__get16be(s); + if (compression > 1) + return stbi__errpuc("bad compression", "PSD has an unknown compression format"); + + // Check size + if (!stbi__mad3sizes_valid(4, w, h, 0)) + return stbi__errpuc("too large", "Corrupt PSD"); + + // Create the destination image. + + if (!compression && bitdepth == 16 && bpc == 16) { + out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0); + ri->bits_per_channel = 16; + } else + out = (stbi_uc *) stbi__malloc(4 * w*h); + + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + pixelCount = w*h; + + // Initialize the data to zero. + //memset( out, 0, pixelCount * 4 ); + + // Finally, the image data. + if (compression) { + // RLE as used by .PSD and .TIFF + // Loop until you get the number of unpacked bytes you are expecting: + // Read the next source byte into n. + // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. + // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. + // Else if n is 128, noop. + // Endloop + + // The RLE-compressed data is preceded by a 2-byte data count for each row in the data, + // which we're going to just skip. + stbi__skip(s, h * channelCount * 2 ); + + // Read the RLE data by channel. + for (channel = 0; channel < 4; channel++) { + stbi_uc *p; + + p = out+channel; + if (channel >= channelCount) { + // Fill this channel with default data. + for (i = 0; i < pixelCount; i++, p += 4) + *p = (channel == 3 ? 255 : 0); + } else { + // Read the RLE data. + if (!stbi__psd_decode_rle(s, p, pixelCount)) { + STBI_FREE(out); + return stbi__errpuc("corrupt", "bad RLE data"); + } + } + } + + } else { + // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) + // where each channel consists of an 8-bit (or 16-bit) value for each pixel in the image. + + // Read the data by channel. + for (channel = 0; channel < 4; channel++) { + if (channel >= channelCount) { + // Fill this channel with default data. + if (bitdepth == 16 && bpc == 16) { + stbi__uint16 *q = ((stbi__uint16 *) out) + channel; + stbi__uint16 val = channel == 3 ? 65535 : 0; + for (i = 0; i < pixelCount; i++, q += 4) + *q = val; + } else { + stbi_uc *p = out+channel; + stbi_uc val = channel == 3 ? 255 : 0; + for (i = 0; i < pixelCount; i++, p += 4) + *p = val; + } + } else { + if (ri->bits_per_channel == 16) { // output bpc + stbi__uint16 *q = ((stbi__uint16 *) out) + channel; + for (i = 0; i < pixelCount; i++, q += 4) + *q = (stbi__uint16) stbi__get16be(s); + } else { + stbi_uc *p = out+channel; + if (bitdepth == 16) { // input bpc + for (i = 0; i < pixelCount; i++, p += 4) + *p = (stbi_uc) (stbi__get16be(s) >> 8); + } else { + for (i = 0; i < pixelCount; i++, p += 4) + *p = stbi__get8(s); + } + } + } + } + } + + // remove weird white matte from PSD + if (channelCount >= 4) { + if (ri->bits_per_channel == 16) { + for (i=0; i < w*h; ++i) { + stbi__uint16 *pixel = (stbi__uint16 *) out + 4*i; + if (pixel[3] != 0 && pixel[3] != 65535) { + float a = pixel[3] / 65535.0f; + float ra = 1.0f / a; + float inv_a = 65535.0f * (1 - ra); + pixel[0] = (stbi__uint16) (pixel[0]*ra + inv_a); + pixel[1] = (stbi__uint16) (pixel[1]*ra + inv_a); + pixel[2] = (stbi__uint16) (pixel[2]*ra + inv_a); + } + } + } else { + for (i=0; i < w*h; ++i) { + unsigned char *pixel = out + 4*i; + if (pixel[3] != 0 && pixel[3] != 255) { + float a = pixel[3] / 255.0f; + float ra = 1.0f / a; + float inv_a = 255.0f * (1 - ra); + pixel[0] = (unsigned char) (pixel[0]*ra + inv_a); + pixel[1] = (unsigned char) (pixel[1]*ra + inv_a); + pixel[2] = (unsigned char) (pixel[2]*ra + inv_a); + } + } + } + } + + // convert to desired output format + if (req_comp && req_comp != 4) { + if (ri->bits_per_channel == 16) + out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, 4, req_comp, w, h); + else + out = stbi__convert_format(out, 4, req_comp, w, h); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + + if (comp) *comp = 4; + *y = h; + *x = w; + + return out; +} +#endif + +// ************************************************************************************************* +// Softimage PIC loader +// by Tom Seddon +// +// See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format +// See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ + +#ifndef STBI_NO_PIC +static int stbi__pic_is4(stbi__context *s,const char *str) +{ + int i; + for (i=0; i<4; ++i) + if (stbi__get8(s) != (stbi_uc)str[i]) + return 0; + + return 1; +} + +static int stbi__pic_test_core(stbi__context *s) +{ + int i; + + if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) + return 0; + + for(i=0;i<84;++i) + stbi__get8(s); + + if (!stbi__pic_is4(s,"PICT")) + return 0; + + return 1; +} + +typedef struct +{ + stbi_uc size,type,channel; +} stbi__pic_packet; + +static stbi_uc *stbi__readval(stbi__context *s, int channel, stbi_uc *dest) +{ + int mask=0x80, i; + + for (i=0; i<4; ++i, mask>>=1) { + if (channel & mask) { + if (stbi__at_eof(s)) return stbi__errpuc("bad file","PIC file too short"); + dest[i]=stbi__get8(s); + } + } + + return dest; +} + +static void stbi__copyval(int channel,stbi_uc *dest,const stbi_uc *src) +{ + int mask=0x80,i; + + for (i=0;i<4; ++i, mask>>=1) + if (channel&mask) + dest[i]=src[i]; +} + +static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *comp, stbi_uc *result) +{ + int act_comp=0,num_packets=0,y,chained; + stbi__pic_packet packets[10]; + + // this will (should...) cater for even some bizarre stuff like having data + // for the same channel in multiple packets. + do { + stbi__pic_packet *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return stbi__errpuc("bad format","too many packets"); + + packet = &packets[num_packets++]; + + chained = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); + packet->channel = stbi__get8(s); + + act_comp |= packet->channel; + + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (reading packets)"); + if (packet->size != 8) return stbi__errpuc("bad format","packet isn't 8bpp"); + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? + + for(y=0; ytype) { + default: + return stbi__errpuc("bad format","packet has bad compression type"); + + case 0: {//uncompressed + int x; + + for(x=0;xchannel,dest)) + return 0; + break; + } + + case 1://Pure RLE + { + int left=width, i; + + while (left>0) { + stbi_uc count,value[4]; + + count=stbi__get8(s); + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pure read count)"); + + if (count > left) + count = (stbi_uc) left; + + if (!stbi__readval(s,packet->channel,value)) return 0; + + for(i=0; ichannel,dest,value); + left -= count; + } + } + break; + + case 2: {//Mixed RLE + int left=width; + while (left>0) { + int count = stbi__get8(s), i; + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (mixed read count)"); + + if (count >= 128) { // Repeated + stbi_uc value[4]; + + if (count==128) + count = stbi__get16be(s); + else + count -= 127; + if (count > left) + return stbi__errpuc("bad file","scanline overrun"); + + if (!stbi__readval(s,packet->channel,value)) + return 0; + + for(i=0;ichannel,dest,value); + } else { // Raw + ++count; + if (count>left) return stbi__errpuc("bad file","scanline overrun"); + + for(i=0;ichannel,dest)) + return 0; + } + left-=count; + } + break; + } + } + } + } + + return result; +} + +static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri) +{ + stbi_uc *result; + int i, x,y, internal_comp; + STBI_NOTUSED(ri); + + if (!comp) comp = &internal_comp; + + for (i=0; i<92; ++i) + stbi__get8(s); + + x = stbi__get16be(s); + y = stbi__get16be(s); + if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)"); + if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode"); + + stbi__get32be(s); //skip `ratio' + stbi__get16be(s); //skip `fields' + stbi__get16be(s); //skip `pad' + + // intermediate buffer is RGBA + result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0); + memset(result, 0xff, x*y*4); + + if (!stbi__pic_load_core(s,x,y,comp, result)) { + STBI_FREE(result); + result=0; + } + *px = x; + *py = y; + if (req_comp == 0) req_comp = *comp; + result=stbi__convert_format(result,4,req_comp,x,y); + + return result; +} + +static int stbi__pic_test(stbi__context *s) +{ + int r = stbi__pic_test_core(s); + stbi__rewind(s); + return r; +} +#endif + +// ************************************************************************************************* +// GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb + +#ifndef STBI_NO_GIF +typedef struct +{ + stbi__int16 prefix; + stbi_uc first; + stbi_uc suffix; +} stbi__gif_lzw; + +typedef struct +{ + int w,h; + stbi_uc *out; // output buffer (always 4 components) + stbi_uc *background; // The current "background" as far as a gif is concerned + stbi_uc *history; + int flags, bgindex, ratio, transparent, eflags; + stbi_uc pal[256][4]; + stbi_uc lpal[256][4]; + stbi__gif_lzw codes[8192]; + stbi_uc *color_table; + int parse, step; + int lflags; + int start_x, start_y; + int max_x, max_y; + int cur_x, cur_y; + int line_size; + int delay; +} stbi__gif; + +static int stbi__gif_test_raw(stbi__context *s) +{ + int sz; + if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') return 0; + sz = stbi__get8(s); + if (sz != '9' && sz != '7') return 0; + if (stbi__get8(s) != 'a') return 0; + return 1; +} + +static int stbi__gif_test(stbi__context *s) +{ + int r = stbi__gif_test_raw(s); + stbi__rewind(s); + return r; +} + +static void stbi__gif_parse_colortable(stbi__context *s, stbi_uc pal[256][4], int num_entries, int transp) +{ + int i; + for (i=0; i < num_entries; ++i) { + pal[i][2] = stbi__get8(s); + pal[i][1] = stbi__get8(s); + pal[i][0] = stbi__get8(s); + pal[i][3] = transp == i ? 0 : 255; + } +} + +static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_info) +{ + stbi_uc version; + if (stbi__get8(s) != 'G' || stbi__get8(s) != 'I' || stbi__get8(s) != 'F' || stbi__get8(s) != '8') + return stbi__err("not GIF", "Corrupt GIF"); + + version = stbi__get8(s); + if (version != '7' && version != '9') return stbi__err("not GIF", "Corrupt GIF"); + if (stbi__get8(s) != 'a') return stbi__err("not GIF", "Corrupt GIF"); + + stbi__g_failure_reason = ""; + g->w = stbi__get16le(s); + g->h = stbi__get16le(s); + g->flags = stbi__get8(s); + g->bgindex = stbi__get8(s); + g->ratio = stbi__get8(s); + g->transparent = -1; + + if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments + + if (is_info) return 1; + + if (g->flags & 0x80) + stbi__gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1); + + return 1; +} + +static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp) +{ + stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif)); + if (!stbi__gif_header(s, g, comp, 1)) { + STBI_FREE(g); + stbi__rewind( s ); + return 0; + } + if (x) *x = g->w; + if (y) *y = g->h; + STBI_FREE(g); + return 1; +} + +static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code) +{ + stbi_uc *p, *c; + int idx; + + // recurse to decode the prefixes, since the linked-list is backwards, + // and working backwards through an interleaved image would be nasty + if (g->codes[code].prefix >= 0) + stbi__out_gif_code(g, g->codes[code].prefix); + + if (g->cur_y >= g->max_y) return; + + idx = g->cur_x + g->cur_y; + p = &g->out[idx]; + g->history[idx / 4] = 1; + + c = &g->color_table[g->codes[code].suffix * 4]; + if (c[3] > 128) { // don't render transparent pixels; + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = c[3]; + } + g->cur_x += 4; + + if (g->cur_x >= g->max_x) { + g->cur_x = g->start_x; + g->cur_y += g->step; + + while (g->cur_y >= g->max_y && g->parse > 0) { + g->step = (1 << g->parse) * g->line_size; + g->cur_y = g->start_y + (g->step >> 1); + --g->parse; + } + } +} + +static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g) +{ + stbi_uc lzw_cs; + stbi__int32 len, init_code; + stbi__uint32 first; + stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; + stbi__gif_lzw *p; + + lzw_cs = stbi__get8(s); + if (lzw_cs > 12) return NULL; + clear = 1 << lzw_cs; + first = 1; + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + bits = 0; + valid_bits = 0; + for (init_code = 0; init_code < clear; init_code++) { + g->codes[init_code].prefix = -1; + g->codes[init_code].first = (stbi_uc) init_code; + g->codes[init_code].suffix = (stbi_uc) init_code; + } + + // support no starting clear code + avail = clear+2; + oldcode = -1; + + len = 0; + for(;;) { + if (valid_bits < codesize) { + if (len == 0) { + len = stbi__get8(s); // start new block + if (len == 0) + return g->out; + } + --len; + bits |= (stbi__int32) stbi__get8(s) << valid_bits; + valid_bits += 8; + } else { + stbi__int32 code = bits & codemask; + bits >>= codesize; + valid_bits -= codesize; + // @OPTIMIZE: is there some way we can accelerate the non-clear path? + if (code == clear) { // clear code + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + avail = clear + 2; + oldcode = -1; + first = 0; + } else if (code == clear + 1) { // end of stream code + stbi__skip(s, len); + while ((len = stbi__get8(s)) > 0) + stbi__skip(s,len); + return g->out; + } else if (code <= avail) { + if (first) { + return stbi__errpuc("no clear code", "Corrupt GIF"); + } + + if (oldcode >= 0) { + p = &g->codes[avail++]; + if (avail > 8192) { + return stbi__errpuc("too many codes", "Corrupt GIF"); + } + + p->prefix = (stbi__int16) oldcode; + p->first = g->codes[oldcode].first; + p->suffix = (code == avail) ? p->first : g->codes[code].first; + } else if (code == avail) + return stbi__errpuc("illegal code in raster", "Corrupt GIF"); + + stbi__out_gif_code(g, (stbi__uint16) code); + + if ((avail & codemask) == 0 && avail <= 0x0FFF) { + codesize++; + codemask = (1 << codesize) - 1; + } + + oldcode = code; + } else { + return stbi__errpuc("illegal code in raster", "Corrupt GIF"); + } + } + } +} + +// this function is designed to support animated gifs, although stb_image doesn't support it +// two back is the image from two frames ago, used for a very specific disposal format +static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp, stbi_uc *two_back) +{ + int dispose; + int first_frame; + int pi; + int pcount; + STBI_NOTUSED(req_comp); + + // on first frame, any non-written pixels get the background colour (non-transparent) + first_frame = 0; + if (g->out == 0) { + if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header + if (!stbi__mad3sizes_valid(4, g->w, g->h, 0)) + return stbi__errpuc("too large", "GIF image is too large"); + pcount = g->w * g->h; + g->out = (stbi_uc *) stbi__malloc(4 * pcount); + g->background = (stbi_uc *) stbi__malloc(4 * pcount); + g->history = (stbi_uc *) stbi__malloc(pcount); + if (!g->out || !g->background || !g->history) + return stbi__errpuc("outofmem", "Out of memory"); + + // image is treated as "transparent" at the start - ie, nothing overwrites the current background; + // background colour is only used for pixels that are not rendered first frame, after that "background" + // color refers to the color that was there the previous frame. + memset(g->out, 0x00, 4 * pcount); + memset(g->background, 0x00, 4 * pcount); // state of the background (starts transparent) + memset(g->history, 0x00, pcount); // pixels that were affected previous frame + first_frame = 1; + } else { + // second frame - how do we dispoase of the previous one? + dispose = (g->eflags & 0x1C) >> 2; + pcount = g->w * g->h; + + if ((dispose == 3) && (two_back == 0)) { + dispose = 2; // if I don't have an image to revert back to, default to the old background + } + + if (dispose == 3) { // use previous graphic + for (pi = 0; pi < pcount; ++pi) { + if (g->history[pi]) { + memcpy( &g->out[pi * 4], &two_back[pi * 4], 4 ); + } + } + } else if (dispose == 2) { + // restore what was changed last frame to background before that frame; + for (pi = 0; pi < pcount; ++pi) { + if (g->history[pi]) { + memcpy( &g->out[pi * 4], &g->background[pi * 4], 4 ); + } + } + } else { + // This is a non-disposal case eithe way, so just + // leave the pixels as is, and they will become the new background + // 1: do not dispose + // 0: not specified. + } + + // background is what out is after the undoing of the previou frame; + memcpy( g->background, g->out, 4 * g->w * g->h ); + } + + // clear my history; + memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame + + for (;;) { + int tag = stbi__get8(s); + switch (tag) { + case 0x2C: /* Image Descriptor */ + { + stbi__int32 x, y, w, h; + stbi_uc *o; + + x = stbi__get16le(s); + y = stbi__get16le(s); + w = stbi__get16le(s); + h = stbi__get16le(s); + if (((x + w) > (g->w)) || ((y + h) > (g->h))) + return stbi__errpuc("bad Image Descriptor", "Corrupt GIF"); + + g->line_size = g->w * 4; + g->start_x = x * 4; + g->start_y = y * g->line_size; + g->max_x = g->start_x + w * 4; + g->max_y = g->start_y + h * g->line_size; + g->cur_x = g->start_x; + g->cur_y = g->start_y; + + // if the width of the specified rectangle is 0, that means + // we may not see *any* pixels or the image is malformed; + // to make sure this is caught, move the current y down to + // max_y (which is what out_gif_code checks). + if (w == 0) + g->cur_y = g->max_y; + + g->lflags = stbi__get8(s); + + if (g->lflags & 0x40) { + g->step = 8 * g->line_size; // first interlaced spacing + g->parse = 3; + } else { + g->step = g->line_size; + g->parse = 0; + } + + if (g->lflags & 0x80) { + stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); + g->color_table = (stbi_uc *) g->lpal; + } else if (g->flags & 0x80) { + g->color_table = (stbi_uc *) g->pal; + } else + return stbi__errpuc("missing color table", "Corrupt GIF"); + + o = stbi__process_gif_raster(s, g); + if (!o) return NULL; + + // if this was the first frame, + pcount = g->w * g->h; + if (first_frame && (g->bgindex > 0)) { + // if first frame, any pixel not drawn to gets the background color + for (pi = 0; pi < pcount; ++pi) { + if (g->history[pi] == 0) { + g->pal[g->bgindex][3] = 255; // just in case it was made transparent, undo that; It will be reset next frame if need be; + memcpy( &g->out[pi * 4], &g->pal[g->bgindex], 4 ); + } + } + } + + return o; + } + + case 0x21: // Comment Extension. + { + int len; + int ext = stbi__get8(s); + if (ext == 0xF9) { // Graphic Control Extension. + len = stbi__get8(s); + if (len == 4) { + g->eflags = stbi__get8(s); + g->delay = 10 * stbi__get16le(s); // delay - 1/100th of a second, saving as 1/1000ths. + + // unset old transparent + if (g->transparent >= 0) { + g->pal[g->transparent][3] = 255; + } + if (g->eflags & 0x01) { + g->transparent = stbi__get8(s); + if (g->transparent >= 0) { + g->pal[g->transparent][3] = 0; + } + } else { + // don't need transparent + stbi__skip(s, 1); + g->transparent = -1; + } + } else { + stbi__skip(s, len); + break; + } + } + while ((len = stbi__get8(s)) != 0) { + stbi__skip(s, len); + } + break; + } + + case 0x3B: // gif stream termination code + return (stbi_uc *) s; // using '1' causes warning on some compilers + + default: + return stbi__errpuc("unknown code", "Corrupt GIF"); + } + } +} + +static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, int *z, int *comp, int req_comp) +{ + if (stbi__gif_test(s)) { + int layers = 0; + stbi_uc *u = 0; + stbi_uc *out = 0; + stbi_uc *two_back = 0; + stbi__gif g; + int stride; + memset(&g, 0, sizeof(g)); + if (delays) { + *delays = 0; + } + + do { + u = stbi__gif_load_next(s, &g, comp, req_comp, two_back); + if (u == (stbi_uc *) s) u = 0; // end of animated gif marker + + if (u) { + *x = g.w; + *y = g.h; + ++layers; + stride = g.w * g.h * 4; + + if (out) { + void *tmp = (stbi_uc*) STBI_REALLOC( out, layers * stride ); + if (NULL == tmp) { + STBI_FREE(g.out); + STBI_FREE(g.history); + STBI_FREE(g.background); + return stbi__errpuc("outofmem", "Out of memory"); + } + else + out = (stbi_uc*) tmp; + if (delays) { + *delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers ); + } + } else { + out = (stbi_uc*)stbi__malloc( layers * stride ); + if (delays) { + *delays = (int*) stbi__malloc( layers * sizeof(int) ); + } + } + memcpy( out + ((layers - 1) * stride), u, stride ); + if (layers >= 2) { + two_back = out - 2 * stride; + } + + if (delays) { + (*delays)[layers - 1U] = g.delay; + } + } + } while (u != 0); + + // free temp buffer; + STBI_FREE(g.out); + STBI_FREE(g.history); + STBI_FREE(g.background); + + // do the final conversion after loading everything; + if (req_comp && req_comp != 4) + out = stbi__convert_format(out, 4, req_comp, layers * g.w, g.h); + + *z = layers; + return out; + } else { + return stbi__errpuc("not GIF", "Image was not as a gif type."); + } +} + +static void *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi_uc *u = 0; + stbi__gif g; + memset(&g, 0, sizeof(g)); + STBI_NOTUSED(ri); + + u = stbi__gif_load_next(s, &g, comp, req_comp, 0); + if (u == (stbi_uc *) s) u = 0; // end of animated gif marker + if (u) { + *x = g.w; + *y = g.h; + + // moved conversion to after successful load so that the same + // can be done for multiple frames. + if (req_comp && req_comp != 4) + u = stbi__convert_format(u, 4, req_comp, g.w, g.h); + } else if (g.out) { + // if there was an error and we allocated an image buffer, free it! + STBI_FREE(g.out); + } + + // free buffers needed for multiple frame loading; + STBI_FREE(g.history); + STBI_FREE(g.background); + + return u; +} + +static int stbi__gif_info(stbi__context *s, int *x, int *y, int *comp) +{ + return stbi__gif_info_raw(s,x,y,comp); +} +#endif + +// ************************************************************************************************* +// Radiance RGBE HDR loader +// originally by Nicolas Schulz +#ifndef STBI_NO_HDR +static int stbi__hdr_test_core(stbi__context *s, const char *signature) +{ + int i; + for (i=0; signature[i]; ++i) + if (stbi__get8(s) != signature[i]) + return 0; + stbi__rewind(s); + return 1; +} + +static int stbi__hdr_test(stbi__context* s) +{ + int r = stbi__hdr_test_core(s, "#?RADIANCE\n"); + stbi__rewind(s); + if(!r) { + r = stbi__hdr_test_core(s, "#?RGBE\n"); + stbi__rewind(s); + } + return r; +} + +#define STBI__HDR_BUFLEN 1024 +static char *stbi__hdr_gettoken(stbi__context *z, char *buffer) +{ + int len=0; + char c = '\0'; + + c = (char) stbi__get8(z); + + while (!stbi__at_eof(z) && c != '\n') { + buffer[len++] = c; + if (len == STBI__HDR_BUFLEN-1) { + // flush to end of line + while (!stbi__at_eof(z) && stbi__get8(z) != '\n') + ; + break; + } + c = (char) stbi__get8(z); + } + + buffer[len] = 0; + return buffer; +} + +static void stbi__hdr_convert(float *output, stbi_uc *input, int req_comp) +{ + if ( input[3] != 0 ) { + float f1; + // Exponent + f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); + if (req_comp <= 2) + output[0] = (input[0] + input[1] + input[2]) * f1 / 3; + else { + output[0] = input[0] * f1; + output[1] = input[1] * f1; + output[2] = input[2] * f1; + } + if (req_comp == 2) output[1] = 1; + if (req_comp == 4) output[3] = 1; + } else { + switch (req_comp) { + case 4: output[3] = 1; /* fallthrough */ + case 3: output[0] = output[1] = output[2] = 0; + break; + case 2: output[1] = 1; /* fallthrough */ + case 1: output[0] = 0; + break; + } + } +} + +static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + char buffer[STBI__HDR_BUFLEN]; + char *token; + int valid = 0; + int width, height; + stbi_uc *scanline; + float *hdr_data; + int len; + unsigned char count, value; + int i, j, k, c1,c2, z; + const char *headerToken; + STBI_NOTUSED(ri); + + // Check identifier + headerToken = stbi__hdr_gettoken(s,buffer); + if (strcmp(headerToken, "#?RADIANCE") != 0 && strcmp(headerToken, "#?RGBE") != 0) + return stbi__errpf("not HDR", "Corrupt HDR image"); + + // Parse header + for(;;) { + token = stbi__hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) return stbi__errpf("unsupported format", "Unsupported HDR format"); + + // Parse width and height + // can't use sscanf() if we're not using stdio! + token = stbi__hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token += 3; + height = (int) strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) return stbi__errpf("unsupported data layout", "Unsupported HDR format"); + token += 3; + width = (int) strtol(token, NULL, 10); + + *x = width; + *y = height; + + if (comp) *comp = 3; + if (req_comp == 0) req_comp = 3; + + if (!stbi__mad4sizes_valid(width, height, req_comp, sizeof(float), 0)) + return stbi__errpf("too large", "HDR image is too large"); + + // Read data + hdr_data = (float *) stbi__malloc_mad4(width, height, req_comp, sizeof(float), 0); + if (!hdr_data) + return stbi__errpf("outofmem", "Out of memory"); + + // Load image data + // image data is stored as some number of sca + if ( width < 8 || width >= 32768) { + // Read flat data + for (j=0; j < height; ++j) { + for (i=0; i < width; ++i) { + stbi_uc rgbe[4]; + main_decode_loop: + stbi__getn(s, rgbe, 4); + stbi__hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); + } + } + } else { + // Read RLE-encoded data + scanline = NULL; + + for (j = 0; j < height; ++j) { + c1 = stbi__get8(s); + c2 = stbi__get8(s); + len = stbi__get8(s); + if (c1 != 2 || c2 != 2 || (len & 0x80)) { + // not run-length encoded, so we have to actually use THIS data as a decoded + // pixel (note this can't be a valid pixel--one of RGB must be >= 128) + stbi_uc rgbe[4]; + rgbe[0] = (stbi_uc) c1; + rgbe[1] = (stbi_uc) c2; + rgbe[2] = (stbi_uc) len; + rgbe[3] = (stbi_uc) stbi__get8(s); + stbi__hdr_convert(hdr_data, rgbe, req_comp); + i = 1; + j = 0; + STBI_FREE(scanline); + goto main_decode_loop; // yes, this makes no sense + } + len <<= 8; + len |= stbi__get8(s); + if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); } + if (scanline == NULL) { + scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0); + if (!scanline) { + STBI_FREE(hdr_data); + return stbi__errpf("outofmem", "Out of memory"); + } + } + + for (k = 0; k < 4; ++k) { + int nleft; + i = 0; + while ((nleft = width - i) > 0) { + count = stbi__get8(s); + if (count > 128) { + // Run + value = stbi__get8(s); + count -= 128; + if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = value; + } else { + // Dump + if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); } + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = stbi__get8(s); + } + } + } + for (i=0; i < width; ++i) + stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); + } + if (scanline) + STBI_FREE(scanline); + } + + return hdr_data; +} + +static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp) +{ + char buffer[STBI__HDR_BUFLEN]; + char *token; + int valid = 0; + int dummy; + + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + + if (stbi__hdr_test(s) == 0) { + stbi__rewind( s ); + return 0; + } + + for(;;) { + token = stbi__hdr_gettoken(s,buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } + + if (!valid) { + stbi__rewind( s ); + return 0; + } + token = stbi__hdr_gettoken(s,buffer); + if (strncmp(token, "-Y ", 3)) { + stbi__rewind( s ); + return 0; + } + token += 3; + *y = (int) strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) { + stbi__rewind( s ); + return 0; + } + token += 3; + *x = (int) strtol(token, NULL, 10); + *comp = 3; + return 1; +} +#endif // STBI_NO_HDR + +#ifndef STBI_NO_BMP +static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp) +{ + void *p; + stbi__bmp_data info; + + info.all_a = 255; + p = stbi__bmp_parse_header(s, &info); + stbi__rewind( s ); + if (p == NULL) + return 0; + if (x) *x = s->img_x; + if (y) *y = s->img_y; + if (comp) { + if (info.bpp == 24 && info.ma == 0xff000000) + *comp = 3; + else + *comp = info.ma ? 4 : 3; + } + return 1; +} +#endif + +#ifndef STBI_NO_PSD +static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp) +{ + int channelCount, dummy, depth; + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + if (stbi__get32be(s) != 0x38425053) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 1) { + stbi__rewind( s ); + return 0; + } + stbi__skip(s, 6); + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) { + stbi__rewind( s ); + return 0; + } + *y = stbi__get32be(s); + *x = stbi__get32be(s); + depth = stbi__get16be(s); + if (depth != 8 && depth != 16) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 3) { + stbi__rewind( s ); + return 0; + } + *comp = 4; + return 1; +} + +static int stbi__psd_is16(stbi__context *s) +{ + int channelCount, depth; + if (stbi__get32be(s) != 0x38425053) { + stbi__rewind( s ); + return 0; + } + if (stbi__get16be(s) != 1) { + stbi__rewind( s ); + return 0; + } + stbi__skip(s, 6); + channelCount = stbi__get16be(s); + if (channelCount < 0 || channelCount > 16) { + stbi__rewind( s ); + return 0; + } + (void) stbi__get32be(s); + (void) stbi__get32be(s); + depth = stbi__get16be(s); + if (depth != 16) { + stbi__rewind( s ); + return 0; + } + return 1; +} +#endif + +#ifndef STBI_NO_PIC +static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp) +{ + int act_comp=0,num_packets=0,chained,dummy; + stbi__pic_packet packets[10]; + + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + + if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) { + stbi__rewind(s); + return 0; + } + + stbi__skip(s, 88); + + *x = stbi__get16be(s); + *y = stbi__get16be(s); + if (stbi__at_eof(s)) { + stbi__rewind( s); + return 0; + } + if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) { + stbi__rewind( s ); + return 0; + } + + stbi__skip(s, 8); + + do { + stbi__pic_packet *packet; + + if (num_packets==sizeof(packets)/sizeof(packets[0])) + return 0; + + packet = &packets[num_packets++]; + chained = stbi__get8(s); + packet->size = stbi__get8(s); + packet->type = stbi__get8(s); + packet->channel = stbi__get8(s); + act_comp |= packet->channel; + + if (stbi__at_eof(s)) { + stbi__rewind( s ); + return 0; + } + if (packet->size != 8) { + stbi__rewind( s ); + return 0; + } + } while (chained); + + *comp = (act_comp & 0x10 ? 4 : 3); + + return 1; +} +#endif + +// ************************************************************************************************* +// Portable Gray Map and Portable Pixel Map loader +// by Ken Miller +// +// PGM: http://netpbm.sourceforge.net/doc/pgm.html +// PPM: http://netpbm.sourceforge.net/doc/ppm.html +// +// Known limitations: +// Does not support comments in the header section +// Does not support ASCII image data (formats P2 and P3) +// Does not support 16-bit-per-channel + +#ifndef STBI_NO_PNM + +static int stbi__pnm_test(stbi__context *s) +{ + char p, t; + p = (char) stbi__get8(s); + t = (char) stbi__get8(s); + if (p != 'P' || (t != '5' && t != '6')) { + stbi__rewind( s ); + return 0; + } + return 1; +} + +static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) +{ + stbi_uc *out; + STBI_NOTUSED(ri); + + if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n)) + return 0; + + *x = s->img_x; + *y = s->img_y; + if (comp) *comp = s->img_n; + + if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0)) + return stbi__errpuc("too large", "PNM too large"); + + out = (stbi_uc *) stbi__malloc_mad3(s->img_n, s->img_x, s->img_y, 0); + if (!out) return stbi__errpuc("outofmem", "Out of memory"); + stbi__getn(s, out, s->img_n * s->img_x * s->img_y); + + if (req_comp && req_comp != s->img_n) { + out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // stbi__convert_format frees input on failure + } + return out; +} + +static int stbi__pnm_isspace(char c) +{ + return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; +} + +static void stbi__pnm_skip_whitespace(stbi__context *s, char *c) +{ + for (;;) { + while (!stbi__at_eof(s) && stbi__pnm_isspace(*c)) + *c = (char) stbi__get8(s); + + if (stbi__at_eof(s) || *c != '#') + break; + + while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' ) + *c = (char) stbi__get8(s); + } +} + +static int stbi__pnm_isdigit(char c) +{ + return c >= '0' && c <= '9'; +} + +static int stbi__pnm_getinteger(stbi__context *s, char *c) +{ + int value = 0; + + while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) { + value = value*10 + (*c - '0'); + *c = (char) stbi__get8(s); + } + + return value; +} + +static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp) +{ + int maxv, dummy; + char c, p, t; + + if (!x) x = &dummy; + if (!y) y = &dummy; + if (!comp) comp = &dummy; + + stbi__rewind(s); + + // Get identifier + p = (char) stbi__get8(s); + t = (char) stbi__get8(s); + if (p != 'P' || (t != '5' && t != '6')) { + stbi__rewind(s); + return 0; + } + + *comp = (t == '6') ? 3 : 1; // '5' is 1-component .pgm; '6' is 3-component .ppm + + c = (char) stbi__get8(s); + stbi__pnm_skip_whitespace(s, &c); + + *x = stbi__pnm_getinteger(s, &c); // read width + stbi__pnm_skip_whitespace(s, &c); + + *y = stbi__pnm_getinteger(s, &c); // read height + stbi__pnm_skip_whitespace(s, &c); + + maxv = stbi__pnm_getinteger(s, &c); // read max value + + if (maxv > 255) + return stbi__err("max value > 255", "PPM image not 8-bit"); + else + return 1; +} +#endif + +static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp) +{ + #ifndef STBI_NO_JPEG + if (stbi__jpeg_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PNG + if (stbi__png_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_GIF + if (stbi__gif_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_BMP + if (stbi__bmp_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PSD + if (stbi__psd_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PIC + if (stbi__pic_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_PNM + if (stbi__pnm_info(s, x, y, comp)) return 1; + #endif + + #ifndef STBI_NO_HDR + if (stbi__hdr_info(s, x, y, comp)) return 1; + #endif + + // test tga last because it's a crappy test! + #ifndef STBI_NO_TGA + if (stbi__tga_info(s, x, y, comp)) + return 1; + #endif + return stbi__err("unknown image type", "Image not of any known type, or corrupt"); +} + +static int stbi__is_16_main(stbi__context *s) +{ + #ifndef STBI_NO_PNG + if (stbi__png_is16(s)) return 1; + #endif + + #ifndef STBI_NO_PSD + if (stbi__psd_is16(s)) return 1; + #endif + + return 0; +} + +#ifndef STBI_NO_STDIO +STBIDEF int stbi_info(char const *filename, int *x, int *y, int *comp) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result; + if (!f) return stbi__err("can't fopen", "Unable to open file"); + result = stbi_info_from_file(f, x, y, comp); + fclose(f); + return result; +} + +STBIDEF int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) +{ + int r; + stbi__context s; + long pos = ftell(f); + stbi__start_file(&s, f); + r = stbi__info_main(&s,x,y,comp); + fseek(f,pos,SEEK_SET); + return r; +} + +STBIDEF int stbi_is_16_bit(char const *filename) +{ + FILE *f = stbi__fopen(filename, "rb"); + int result; + if (!f) return stbi__err("can't fopen", "Unable to open file"); + result = stbi_is_16_bit_from_file(f); + fclose(f); + return result; +} + +STBIDEF int stbi_is_16_bit_from_file(FILE *f) +{ + int r; + stbi__context s; + long pos = ftell(f); + stbi__start_file(&s, f); + r = stbi__is_16_main(&s); + fseek(f,pos,SEEK_SET); + return r; +} +#endif // !STBI_NO_STDIO + +STBIDEF int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__info_main(&s,x,y,comp); +} + +STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); + return stbi__info_main(&s,x,y,comp); +} + +STBIDEF int stbi_is_16_bit_from_memory(stbi_uc const *buffer, int len) +{ + stbi__context s; + stbi__start_mem(&s,buffer,len); + return stbi__is_16_main(&s); +} + +STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user) +{ + stbi__context s; + stbi__start_callbacks(&s, (stbi_io_callbacks *) c, user); + return stbi__is_16_main(&s); +} + +#endif // STB_IMAGE_IMPLEMENTATION + +/* + revision history: + 2.20 (2019-02-07) support utf8 filenames in Windows; fix warnings and platform ifdefs + 2.19 (2018-02-11) fix warning + 2.18 (2018-01-30) fix warnings + 2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug + 1-bit BMP + *_is_16_bit api + avoid warnings + 2.16 (2017-07-23) all functions have 16-bit variants; + STBI_NO_STDIO works again; + compilation fixes; + fix rounding in unpremultiply; + optimize vertical flip; + disable raw_len validation; + documentation fixes + 2.15 (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode; + warning fixes; disable run-time SSE detection on gcc; + uniform handling of optional "return" values; + thread-safe initialization of zlib tables + 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs + 2.13 (2016-11-29) add 16-bit API, only supported for PNG right now + 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes + 2.11 (2016-04-02) allocate large structures on the stack + remove white matting for transparent PSD + fix reported channel count for PNG & BMP + re-enable SSE2 in non-gcc 64-bit + support RGB-formatted JPEG + read 16-bit PNGs (only as 8-bit) + 2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED + 2.09 (2016-01-16) allow comments in PNM files + 16-bit-per-pixel TGA (not bit-per-component) + info() for TGA could break due to .hdr handling + info() for BMP to shares code instead of sloppy parse + can use STBI_REALLOC_SIZED if allocator doesn't support realloc + code cleanup + 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA + 2.07 (2015-09-13) fix compiler warnings + partial animated GIF support + limited 16-bpc PSD support + #ifdef unused functions + bug with < 92 byte PIC,PNM,HDR,TGA + 2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value + 2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning + 2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit + 2.03 (2015-04-12) extra corruption checking (mmozeiko) + stbi_set_flip_vertically_on_load (nguillemot) + fix NEON support; fix mingw support + 2.02 (2015-01-19) fix incorrect assert, fix warning + 2.01 (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2 + 2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG + 2.00 (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg) + progressive JPEG (stb) + PGM/PPM support (Ken Miller) + STBI_MALLOC,STBI_REALLOC,STBI_FREE + GIF bugfix -- seemingly never worked + STBI_NO_*, STBI_ONLY_* + 1.48 (2014-12-14) fix incorrectly-named assert() + 1.47 (2014-12-14) 1/2/4-bit PNG support, both direct and paletted (Omar Cornut & stb) + optimize PNG (ryg) + fix bug in interlaced PNG with user-specified channel count (stb) + 1.46 (2014-08-26) + fix broken tRNS chunk (colorkey-style transparency) in non-paletted PNG + 1.45 (2014-08-16) + fix MSVC-ARM internal compiler error by wrapping malloc + 1.44 (2014-08-07) + various warning fixes from Ronny Chevalier + 1.43 (2014-07-15) + fix MSVC-only compiler problem in code changed in 1.42 + 1.42 (2014-07-09) + don't define _CRT_SECURE_NO_WARNINGS (affects user code) + fixes to stbi__cleanup_jpeg path + added STBI_ASSERT to avoid requiring assert.h + 1.41 (2014-06-25) + fix search&replace from 1.36 that messed up comments/error messages + 1.40 (2014-06-22) + fix gcc struct-initialization warning + 1.39 (2014-06-15) + fix to TGA optimization when req_comp != number of components in TGA; + fix to GIF loading because BMP wasn't rewinding (whoops, no GIFs in my test suite) + add support for BMP version 5 (more ignored fields) + 1.38 (2014-06-06) + suppress MSVC warnings on integer casts truncating values + fix accidental rename of 'skip' field of I/O + 1.37 (2014-06-04) + remove duplicate typedef + 1.36 (2014-06-03) + convert to header file single-file library + if de-iphone isn't set, load iphone images color-swapped instead of returning NULL + 1.35 (2014-05-27) + various warnings + fix broken STBI_SIMD path + fix bug where stbi_load_from_file no longer left file pointer in correct place + fix broken non-easy path for 32-bit BMP (possibly never used) + TGA optimization by Arseny Kapoulkine + 1.34 (unknown) + use STBI_NOTUSED in stbi__resample_row_generic(), fix one more leak in tga failure case + 1.33 (2011-07-14) + make stbi_is_hdr work in STBI_NO_HDR (as specified), minor compiler-friendly improvements + 1.32 (2011-07-13) + support for "info" function for all supported filetypes (SpartanJ) + 1.31 (2011-06-20) + a few more leak fixes, bug in PNG handling (SpartanJ) + 1.30 (2011-06-11) + added ability to load files via callbacks to accomidate custom input streams (Ben Wenger) + removed deprecated format-specific test/load functions + removed support for installable file formats (stbi_loader) -- would have been broken for IO callbacks anyway + error cases in bmp and tga give messages and don't leak (Raymond Barbiero, grisha) + fix inefficiency in decoding 32-bit BMP (David Woo) + 1.29 (2010-08-16) + various warning fixes from Aurelien Pocheville + 1.28 (2010-08-01) + fix bug in GIF palette transparency (SpartanJ) + 1.27 (2010-08-01) + cast-to-stbi_uc to fix warnings + 1.26 (2010-07-24) + fix bug in file buffering for PNG reported by SpartanJ + 1.25 (2010-07-17) + refix trans_data warning (Won Chun) + 1.24 (2010-07-12) + perf improvements reading from files on platforms with lock-heavy fgetc() + minor perf improvements for jpeg + deprecated type-specific functions so we'll get feedback if they're needed + attempt to fix trans_data warning (Won Chun) + 1.23 fixed bug in iPhone support + 1.22 (2010-07-10) + removed image *writing* support + stbi_info support from Jetro Lauha + GIF support from Jean-Marc Lienher + iPhone PNG-extensions from James Brown + warning-fixes from Nicolas Schulz and Janez Zemva (i.stbi__err. Janez (U+017D)emva) + 1.21 fix use of 'stbi_uc' in header (reported by jon blow) + 1.20 added support for Softimage PIC, by Tom Seddon + 1.19 bug in interlaced PNG corruption check (found by ryg) + 1.18 (2008-08-02) + fix a threading bug (local mutable static) + 1.17 support interlaced PNG + 1.16 major bugfix - stbi__convert_format converted one too many pixels + 1.15 initialize some fields for thread safety + 1.14 fix threadsafe conversion bug + header-file-only version (#define STBI_HEADER_FILE_ONLY before including) + 1.13 threadsafe + 1.12 const qualifiers in the API + 1.11 Support installable IDCT, colorspace conversion routines + 1.10 Fixes for 64-bit (don't use "unsigned long") + optimized upsampling by Fabian "ryg" Giesen + 1.09 Fix format-conversion for PSD code (bad global variables!) + 1.08 Thatcher Ulrich's PSD code integrated by Nicolas Schulz + 1.07 attempt to fix C++ warning/errors again + 1.06 attempt to fix C++ warning/errors again + 1.05 fix TGA loading to return correct *comp and use good luminance calc + 1.04 default float alpha is 1, not 255; use 'void *' for stbi_image_free + 1.03 bugfixes to STBI_NO_STDIO, STBI_NO_HDR + 1.02 support for (subset of) HDR files, float interface for preferred access to them + 1.01 fix bug: possible bug in handling right-side up bmps... not sure + fix bug: the stbi__bmp_load() and stbi__tga_load() functions didn't work at all + 1.00 interface to zlib that skips zlib header + 0.99 correct handling of alpha in palette + 0.98 TGA loader by lonesock; dynamically add loaders (untested) + 0.97 jpeg errors on too large a file; also catch another malloc failure + 0.96 fix detection of invalid v value - particleman@mollyrocket forum + 0.95 during header scan, seek to markers in case of padding + 0.94 STBI_NO_STDIO to disable stdio usage; rename all #defines the same + 0.93 handle jpegtran output; verbose errors + 0.92 read 4,8,16,24,32-bit BMP files of several formats + 0.91 output 24-bit Windows 3.0 BMP files + 0.90 fix a few more warnings; bump version number to approach 1.0 + 0.61 bugfixes due to Marc LeBlanc, Christopher Lloyd + 0.60 fix compiling as c++ + 0.59 fix warnings: merge Dave Moore's -Wall fixes + 0.58 fix bug: zlib uncompressed mode len/nlen was wrong endian + 0.57 fix bug: jpg last huffman symbol before marker was >9 bits but less than 16 available + 0.56 fix bug: zlib uncompressed mode len vs. nlen + 0.55 fix bug: restart_interval not initialized to 0 + 0.54 allow NULL for 'int *comp' + 0.53 fix bug in png 3->4; speedup png decoding + 0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments + 0.51 obey req_comp requests, 1-component jpegs return as 1-component, + on 'test' only check type, not whether we support this variant + 0.50 (2006-11-19) + first released version +*/ + + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/stb/stb_image_write.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/stb/stb_image_write.h new file mode 100644 index 00000000..cffd473c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/3rdparty/stb/stb_image_write.h @@ -0,0 +1,1666 @@ +/* stb_image_write - v1.14 - public domain - http://nothings.org/stb + writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015 + no warranty implied; use at your own risk + + Before #including, + + #define STB_IMAGE_WRITE_IMPLEMENTATION + + in the file that you want to have the implementation. + + Will probably not work correctly with strict-aliasing optimizations. + +ABOUT: + + This header file is a library for writing images to C stdio or a callback. + + The PNG output is not optimal; it is 20-50% larger than the file + written by a decent optimizing implementation; though providing a custom + zlib compress function (see STBIW_ZLIB_COMPRESS) can mitigate that. + This library is designed for source code compactness and simplicity, + not optimal image file size or run-time performance. + +BUILDING: + + You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h. + You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace + malloc,realloc,free. + You can #define STBIW_MEMMOVE() to replace memmove() + You can #define STBIW_ZLIB_COMPRESS to use a custom zlib-style compress function + for PNG compression (instead of the builtin one), it must have the following signature: + unsigned char * my_compress(unsigned char *data, int data_len, int *out_len, int quality); + The returned data will be freed with STBIW_FREE() (free() by default), + so it must be heap allocated with STBIW_MALLOC() (malloc() by default), + +UNICODE: + + If compiling for Windows and you wish to use Unicode filenames, compile + with + #define STBIW_WINDOWS_UTF8 + and pass utf8-encoded filenames. Call stbiw_convert_wchar_to_utf8 to convert + Windows wchar_t filenames to utf8. + +USAGE: + + There are five functions, one for each image file format: + + int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); + int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); + int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); + int stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality); + int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); + + void stbi_flip_vertically_on_write(int flag); // flag is non-zero to flip data vertically + + There are also five equivalent functions that use an arbitrary write function. You are + expected to open/close your file-equivalent before and after calling these: + + int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); + int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); + int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); + int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); + int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality); + + where the callback is: + void stbi_write_func(void *context, void *data, int size); + + You can configure it with these global variables: + int stbi_write_tga_with_rle; // defaults to true; set to 0 to disable RLE + int stbi_write_png_compression_level; // defaults to 8; set to higher for more compression + int stbi_write_force_png_filter; // defaults to -1; set to 0..5 to force a filter mode + + + You can define STBI_WRITE_NO_STDIO to disable the file variant of these + functions, so the library will not use stdio.h at all. However, this will + also disable HDR writing, because it requires stdio for formatted output. + + Each function returns 0 on failure and non-0 on success. + + The functions create an image file defined by the parameters. The image + is a rectangle of pixels stored from left-to-right, top-to-bottom. + Each pixel contains 'comp' channels of data stored interleaved with 8-bits + per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is + monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall. + The *data pointer points to the first byte of the top-left-most pixel. + For PNG, "stride_in_bytes" is the distance in bytes from the first byte of + a row of pixels to the first byte of the next row of pixels. + + PNG creates output files with the same number of components as the input. + The BMP format expands Y to RGB in the file format and does not + output alpha. + + PNG supports writing rectangles of data even when the bytes storing rows of + data are not consecutive in memory (e.g. sub-rectangles of a larger image), + by supplying the stride between the beginning of adjacent rows. The other + formats do not. (Thus you cannot write a native-format BMP through the BMP + writer, both because it is in BGR order and because it may have padding + at the end of the line.) + + PNG allows you to set the deflate compression level by setting the global + variable 'stbi_write_png_compression_level' (it defaults to 8). + + HDR expects linear float data. Since the format is always 32-bit rgb(e) + data, alpha (if provided) is discarded, and for monochrome data it is + replicated across all three channels. + + TGA supports RLE or non-RLE compressed data. To use non-RLE-compressed + data, set the global variable 'stbi_write_tga_with_rle' to 0. + + JPEG does ignore alpha channels in input data; quality is between 1 and 100. + Higher quality looks better but results in a bigger image. + JPEG baseline (no JPEG progressive). + +CREDITS: + + + Sean Barrett - PNG/BMP/TGA + Baldur Karlsson - HDR + Jean-Sebastien Guay - TGA monochrome + Tim Kelsey - misc enhancements + Alan Hickman - TGA RLE + Emmanuel Julien - initial file IO callback implementation + Jon Olick - original jo_jpeg.cpp code + Daniel Gibson - integrate JPEG, allow external zlib + Aarni Koskela - allow choosing PNG filter + + bugfixes: + github:Chribba + Guillaume Chereau + github:jry2 + github:romigrou + Sergio Gonzalez + Jonas Karlsson + Filip Wasil + Thatcher Ulrich + github:poppolopoppo + Patrick Boettcher + github:xeekworx + Cap Petschulat + Simon Rodriguez + Ivan Tikhonov + github:ignotion + Adam Schackart + +LICENSE + + See end of file for license information. + +*/ + +#ifndef INCLUDE_STB_IMAGE_WRITE_H +#define INCLUDE_STB_IMAGE_WRITE_H + +#include + +// if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline' +#ifndef STBIWDEF +#ifdef STB_IMAGE_WRITE_STATIC +#define STBIWDEF static +#else +#ifdef __cplusplus +#define STBIWDEF extern "C" +#else +#define STBIWDEF extern +#endif +#endif +#endif + +#ifndef STB_IMAGE_WRITE_STATIC // C++ forbids static forward declarations +extern int stbi_write_tga_with_rle; +extern int stbi_write_png_compression_level; +extern int stbi_write_force_png_filter; +#endif + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); +STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data); +STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality); + +#ifdef STBI_WINDOWS_UTF8 +STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input); +#endif +#endif + +typedef void stbi_write_func(void *context, void *data, int size); + +STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data, int stride_in_bytes); +STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const void *data); +STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int w, int h, int comp, const float *data); +STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality); + +STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean); + +#endif//INCLUDE_STB_IMAGE_WRITE_H + +#ifdef STB_IMAGE_WRITE_IMPLEMENTATION + +#ifdef _WIN32 + #ifndef _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_WARNINGS + #endif + #ifndef _CRT_NONSTDC_NO_DEPRECATE + #define _CRT_NONSTDC_NO_DEPRECATE + #endif +#endif + +#ifndef STBI_WRITE_NO_STDIO +#include +#endif // STBI_WRITE_NO_STDIO + +#include +#include +#include +#include + +#if defined(STBIW_MALLOC) && defined(STBIW_FREE) && (defined(STBIW_REALLOC) || defined(STBIW_REALLOC_SIZED)) +// ok +#elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC) && !defined(STBIW_REALLOC_SIZED) +// ok +#else +#error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC (or STBIW_REALLOC_SIZED)." +#endif + +#ifndef STBIW_MALLOC +#define STBIW_MALLOC(sz) malloc(sz) +#define STBIW_REALLOC(p,newsz) realloc(p,newsz) +#define STBIW_FREE(p) free(p) +#endif + +#ifndef STBIW_REALLOC_SIZED +#define STBIW_REALLOC_SIZED(p,oldsz,newsz) STBIW_REALLOC(p,newsz) +#endif + + +#ifndef STBIW_MEMMOVE +#define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz) +#endif + + +#ifndef STBIW_ASSERT +#include +#define STBIW_ASSERT(x) assert(x) +#endif + +#define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff) + +#ifdef STB_IMAGE_WRITE_STATIC +static int stbi_write_png_compression_level = 8; +static int stbi_write_tga_with_rle = 1; +static int stbi_write_force_png_filter = -1; +#else +int stbi_write_png_compression_level = 8; +int stbi_write_tga_with_rle = 1; +int stbi_write_force_png_filter = -1; +#endif + +static int stbi__flip_vertically_on_write = 0; + +STBIWDEF void stbi_flip_vertically_on_write(int flag) +{ + stbi__flip_vertically_on_write = flag; +} + +typedef struct +{ + stbi_write_func *func; + void *context; +} stbi__write_context; + +// initialize a callback-based context +static void stbi__start_write_callbacks(stbi__write_context *s, stbi_write_func *c, void *context) +{ + s->func = c; + s->context = context; +} + +#ifndef STBI_WRITE_NO_STDIO + +static void stbi__stdio_write(void *context, void *data, int size) +{ + fwrite(data,1,size,(FILE*) context); +} + +#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) +#ifdef __cplusplus +#define STBIW_EXTERN extern "C" +#else +#define STBIW_EXTERN extern +#endif +STBIW_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide); +STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default); + +STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) +{ + return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); +} +#endif + +static FILE *stbiw__fopen(char const *filename, char const *mode) +{ + FILE *f; +#if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) + wchar_t wMode[64]; + wchar_t wFilename[1024]; + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename))) + return 0; + + if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode))) + return 0; + +#if _MSC_VER >= 1400 + if (0 != _wfopen_s(&f, wFilename, wMode)) + f = 0; +#else + f = _wfopen(wFilename, wMode); +#endif + +#elif defined(_MSC_VER) && _MSC_VER >= 1400 + if (0 != fopen_s(&f, filename, mode)) + f=0; +#else + f = fopen(filename, mode); +#endif + return f; +} + +static int stbi__start_write_file(stbi__write_context *s, const char *filename) +{ + FILE *f = stbiw__fopen(filename, "wb"); + stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f); + return f != NULL; +} + +static void stbi__end_write_file(stbi__write_context *s) +{ + fclose((FILE *)s->context); +} + +#endif // !STBI_WRITE_NO_STDIO + +typedef unsigned int stbiw_uint32; +typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1]; + +static void stbiw__writefv(stbi__write_context *s, const char *fmt, va_list v) +{ + while (*fmt) { + switch (*fmt++) { + case ' ': break; + case '1': { unsigned char x = STBIW_UCHAR(va_arg(v, int)); + s->func(s->context,&x,1); + break; } + case '2': { int x = va_arg(v,int); + unsigned char b[2]; + b[0] = STBIW_UCHAR(x); + b[1] = STBIW_UCHAR(x>>8); + s->func(s->context,b,2); + break; } + case '4': { stbiw_uint32 x = va_arg(v,int); + unsigned char b[4]; + b[0]=STBIW_UCHAR(x); + b[1]=STBIW_UCHAR(x>>8); + b[2]=STBIW_UCHAR(x>>16); + b[3]=STBIW_UCHAR(x>>24); + s->func(s->context,b,4); + break; } + default: + STBIW_ASSERT(0); + return; + } + } +} + +static void stbiw__writef(stbi__write_context *s, const char *fmt, ...) +{ + va_list v; + va_start(v, fmt); + stbiw__writefv(s, fmt, v); + va_end(v); +} + +static void stbiw__putc(stbi__write_context *s, unsigned char c) +{ + s->func(s->context, &c, 1); +} + +static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c) +{ + unsigned char arr[3]; + arr[0] = a; arr[1] = b; arr[2] = c; + s->func(s->context, arr, 3); +} + +static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d) +{ + unsigned char bg[3] = { 255, 0, 255}, px[3]; + int k; + + if (write_alpha < 0) + s->func(s->context, &d[comp - 1], 1); + + switch (comp) { + case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case + case 1: + if (expand_mono) + stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp + else + s->func(s->context, d, 1); // monochrome TGA + break; + case 4: + if (!write_alpha) { + // composite against pink background + for (k = 0; k < 3; ++k) + px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255; + stbiw__write3(s, px[1 - rgb_dir], px[1], px[1 + rgb_dir]); + break; + } + /* FALLTHROUGH */ + case 3: + stbiw__write3(s, d[1 - rgb_dir], d[1], d[1 + rgb_dir]); + break; + } + if (write_alpha > 0) + s->func(s->context, &d[comp - 1], 1); +} + +static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono) +{ + stbiw_uint32 zero = 0; + int i,j, j_end; + + if (y <= 0) + return; + + if (stbi__flip_vertically_on_write) + vdir *= -1; + + if (vdir < 0) { + j_end = -1; j = y-1; + } else { + j_end = y; j = 0; + } + + for (; j != j_end; j += vdir) { + for (i=0; i < x; ++i) { + unsigned char *d = (unsigned char *) data + (j*x+i)*comp; + stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d); + } + s->func(s->context, &zero, scanline_pad); + } +} + +static int stbiw__outfile(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, int expand_mono, void *data, int alpha, int pad, const char *fmt, ...) +{ + if (y < 0 || x < 0) { + return 0; + } else { + va_list v; + va_start(v, fmt); + stbiw__writefv(s, fmt, v); + va_end(v); + stbiw__write_pixels(s,rgb_dir,vdir,x,y,comp,data,alpha,pad, expand_mono); + return 1; + } +} + +static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, const void *data) +{ + int pad = (-x*3) & 3; + return stbiw__outfile(s,-1,-1,x,y,comp,1,(void *) data,0,pad, + "11 4 22 4" "4 44 22 444444", + 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header + 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header +} + +STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) +{ + stbi__write_context s; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_bmp_core(&s, x, y, comp, data); +} + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data) +{ + stbi__write_context s; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_bmp_core(&s, x, y, comp, data); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif //!STBI_WRITE_NO_STDIO + +static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, void *data) +{ + int has_alpha = (comp == 2 || comp == 4); + int colorbytes = has_alpha ? comp-1 : comp; + int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3 + + if (y < 0 || x < 0) + return 0; + + if (!stbi_write_tga_with_rle) { + return stbiw__outfile(s, -1, -1, x, y, comp, 0, (void *) data, has_alpha, 0, + "111 221 2222 11", 0, 0, format, 0, 0, 0, 0, 0, x, y, (colorbytes + has_alpha) * 8, has_alpha * 8); + } else { + int i,j,k; + int jend, jdir; + + stbiw__writef(s, "111 221 2222 11", 0,0,format+8, 0,0,0, 0,0,x,y, (colorbytes + has_alpha) * 8, has_alpha * 8); + + if (stbi__flip_vertically_on_write) { + j = 0; + jend = y; + jdir = 1; + } else { + j = y-1; + jend = -1; + jdir = -1; + } + for (; j != jend; j += jdir) { + unsigned char *row = (unsigned char *) data + j * x * comp; + int len; + + for (i = 0; i < x; i += len) { + unsigned char *begin = row + i * comp; + int diff = 1; + len = 1; + + if (i < x - 1) { + ++len; + diff = memcmp(begin, row + (i + 1) * comp, comp); + if (diff) { + const unsigned char *prev = begin; + for (k = i + 2; k < x && len < 128; ++k) { + if (memcmp(prev, row + k * comp, comp)) { + prev += comp; + ++len; + } else { + --len; + break; + } + } + } else { + for (k = i + 2; k < x && len < 128; ++k) { + if (!memcmp(begin, row + k * comp, comp)) { + ++len; + } else { + break; + } + } + } + } + + if (diff) { + unsigned char header = STBIW_UCHAR(len - 1); + s->func(s->context, &header, 1); + for (k = 0; k < len; ++k) { + stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp); + } + } else { + unsigned char header = STBIW_UCHAR(len - 129); + s->func(s->context, &header, 1); + stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin); + } + } + } + } + return 1; +} + +STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data) +{ + stbi__write_context s; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_tga_core(&s, x, y, comp, (void *) data); +} + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data) +{ + stbi__write_context s; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_tga_core(&s, x, y, comp, (void *) data); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif + +// ************************************************************************************************* +// Radiance RGBE HDR writer +// by Baldur Karlsson + +#define stbiw__max(a, b) ((a) > (b) ? (a) : (b)) + +static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear) +{ + int exponent; + float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2])); + + if (maxcomp < 1e-32f) { + rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0; + } else { + float normalize = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp; + + rgbe[0] = (unsigned char)(linear[0] * normalize); + rgbe[1] = (unsigned char)(linear[1] * normalize); + rgbe[2] = (unsigned char)(linear[2] * normalize); + rgbe[3] = (unsigned char)(exponent + 128); + } +} + +static void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte) +{ + unsigned char lengthbyte = STBIW_UCHAR(length+128); + STBIW_ASSERT(length+128 <= 255); + s->func(s->context, &lengthbyte, 1); + s->func(s->context, &databyte, 1); +} + +static void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data) +{ + unsigned char lengthbyte = STBIW_UCHAR(length); + STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code + s->func(s->context, &lengthbyte, 1); + s->func(s->context, data, length); +} + +static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline) +{ + unsigned char scanlineheader[4] = { 2, 2, 0, 0 }; + unsigned char rgbe[4]; + float linear[3]; + int x; + + scanlineheader[2] = (width&0xff00)>>8; + scanlineheader[3] = (width&0x00ff); + + /* skip RLE for images too small or large */ + if (width < 8 || width >= 32768) { + for (x=0; x < width; x++) { + switch (ncomp) { + case 4: /* fallthrough */ + case 3: linear[2] = scanline[x*ncomp + 2]; + linear[1] = scanline[x*ncomp + 1]; + linear[0] = scanline[x*ncomp + 0]; + break; + default: + linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0]; + break; + } + stbiw__linear_to_rgbe(rgbe, linear); + s->func(s->context, rgbe, 4); + } + } else { + int c,r; + /* encode into scratch buffer */ + for (x=0; x < width; x++) { + switch(ncomp) { + case 4: /* fallthrough */ + case 3: linear[2] = scanline[x*ncomp + 2]; + linear[1] = scanline[x*ncomp + 1]; + linear[0] = scanline[x*ncomp + 0]; + break; + default: + linear[0] = linear[1] = linear[2] = scanline[x*ncomp + 0]; + break; + } + stbiw__linear_to_rgbe(rgbe, linear); + scratch[x + width*0] = rgbe[0]; + scratch[x + width*1] = rgbe[1]; + scratch[x + width*2] = rgbe[2]; + scratch[x + width*3] = rgbe[3]; + } + + s->func(s->context, scanlineheader, 4); + + /* RLE each component separately */ + for (c=0; c < 4; c++) { + unsigned char *comp = &scratch[width*c]; + + x = 0; + while (x < width) { + // find first run + r = x; + while (r+2 < width) { + if (comp[r] == comp[r+1] && comp[r] == comp[r+2]) + break; + ++r; + } + if (r+2 >= width) + r = width; + // dump up to first run + while (x < r) { + int len = r-x; + if (len > 128) len = 128; + stbiw__write_dump_data(s, len, &comp[x]); + x += len; + } + // if there's a run, output it + if (r+2 < width) { // same test as what we break out of in search loop, so only true if we break'd + // find next byte after run + while (r < width && comp[r] == comp[x]) + ++r; + // output run up to r + while (x < r) { + int len = r-x; + if (len > 127) len = 127; + stbiw__write_run_data(s, len, comp[x]); + x += len; + } + } + } + } + } +} + +static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, float *data) +{ + if (y <= 0 || x <= 0 || data == NULL) + return 0; + else { + // Each component is stored separately. Allocate scratch space for full output scanline. + unsigned char *scratch = (unsigned char *) STBIW_MALLOC(x*4); + int i, len; + char buffer[128]; + char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n"; + s->func(s->context, header, sizeof(header)-1); + +#ifdef __STDC_WANT_SECURE_LIB__ + len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); +#else + len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); +#endif + s->func(s->context, buffer, len); + + for(i=0; i < y; i++) + stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i)); + STBIW_FREE(scratch); + return 1; + } +} + +STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data) +{ + stbi__write_context s; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_hdr_core(&s, x, y, comp, (float *) data); +} + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data) +{ + stbi__write_context s; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif // STBI_WRITE_NO_STDIO + + +////////////////////////////////////////////////////////////////////////////// +// +// PNG writer +// + +#ifndef STBIW_ZLIB_COMPRESS +// stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size() +#define stbiw__sbraw(a) ((int *) (void *) (a) - 2) +#define stbiw__sbm(a) stbiw__sbraw(a)[0] +#define stbiw__sbn(a) stbiw__sbraw(a)[1] + +#define stbiw__sbneedgrow(a,n) ((a)==0 || stbiw__sbn(a)+n >= stbiw__sbm(a)) +#define stbiw__sbmaybegrow(a,n) (stbiw__sbneedgrow(a,(n)) ? stbiw__sbgrow(a,n) : 0) +#define stbiw__sbgrow(a,n) stbiw__sbgrowf((void **) &(a), (n), sizeof(*(a))) + +#define stbiw__sbpush(a, v) (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v)) +#define stbiw__sbcount(a) ((a) ? stbiw__sbn(a) : 0) +#define stbiw__sbfree(a) ((a) ? STBIW_FREE(stbiw__sbraw(a)),0 : 0) + +static void *stbiw__sbgrowf(void **arr, int increment, int itemsize) +{ + int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1; + void *p = STBIW_REALLOC_SIZED(*arr ? stbiw__sbraw(*arr) : 0, *arr ? (stbiw__sbm(*arr)*itemsize + sizeof(int)*2) : 0, itemsize * m + sizeof(int)*2); + STBIW_ASSERT(p); + if (p) { + if (!*arr) ((int *) p)[1] = 0; + *arr = (void *) ((int *) p + 2); + stbiw__sbm(*arr) = m; + } + return *arr; +} + +static unsigned char *stbiw__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount) +{ + while (*bitcount >= 8) { + stbiw__sbpush(data, STBIW_UCHAR(*bitbuffer)); + *bitbuffer >>= 8; + *bitcount -= 8; + } + return data; +} + +static int stbiw__zlib_bitrev(int code, int codebits) +{ + int res=0; + while (codebits--) { + res = (res << 1) | (code & 1); + code >>= 1; + } + return res; +} + +static unsigned int stbiw__zlib_countm(unsigned char *a, unsigned char *b, int limit) +{ + int i; + for (i=0; i < limit && i < 258; ++i) + if (a[i] != b[i]) break; + return i; +} + +static unsigned int stbiw__zhash(unsigned char *data) +{ + stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16); + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + return hash; +} + +#define stbiw__zlib_flush() (out = stbiw__zlib_flushf(out, &bitbuf, &bitcount)) +#define stbiw__zlib_add(code,codebits) \ + (bitbuf |= (code) << bitcount, bitcount += (codebits), stbiw__zlib_flush()) +#define stbiw__zlib_huffa(b,c) stbiw__zlib_add(stbiw__zlib_bitrev(b,c),c) +// default huffman tables +#define stbiw__zlib_huff1(n) stbiw__zlib_huffa(0x30 + (n), 8) +#define stbiw__zlib_huff2(n) stbiw__zlib_huffa(0x190 + (n)-144, 9) +#define stbiw__zlib_huff3(n) stbiw__zlib_huffa(0 + (n)-256,7) +#define stbiw__zlib_huff4(n) stbiw__zlib_huffa(0xc0 + (n)-280,8) +#define stbiw__zlib_huff(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : (n) <= 255 ? stbiw__zlib_huff2(n) : (n) <= 279 ? stbiw__zlib_huff3(n) : stbiw__zlib_huff4(n)) +#define stbiw__zlib_huffb(n) ((n) <= 143 ? stbiw__zlib_huff1(n) : stbiw__zlib_huff2(n)) + +#define stbiw__ZHASH 16384 + +#endif // STBIW_ZLIB_COMPRESS + +STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality) +{ +#ifdef STBIW_ZLIB_COMPRESS + // user provided a zlib compress implementation, use that + return STBIW_ZLIB_COMPRESS(data, data_len, out_len, quality); +#else // use builtin + static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 }; + static unsigned char lengtheb[]= { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 }; + static unsigned short distc[] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 }; + static unsigned char disteb[] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; + unsigned int bitbuf=0; + int i,j, bitcount=0; + unsigned char *out = NULL; + unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(unsigned char**)); + if (hash_table == NULL) + return NULL; + if (quality < 5) quality = 5; + + stbiw__sbpush(out, 0x78); // DEFLATE 32K window + stbiw__sbpush(out, 0x5e); // FLEVEL = 1 + stbiw__zlib_add(1,1); // BFINAL = 1 + stbiw__zlib_add(1,2); // BTYPE = 1 -- fixed huffman + + for (i=0; i < stbiw__ZHASH; ++i) + hash_table[i] = NULL; + + i=0; + while (i < data_len-3) { + // hash next 3 bytes of data to be compressed + int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3; + unsigned char *bestloc = 0; + unsigned char **hlist = hash_table[h]; + int n = stbiw__sbcount(hlist); + for (j=0; j < n; ++j) { + if (hlist[j]-data > i-32768) { // if entry lies within window + int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i); + if (d >= best) { best=d; bestloc=hlist[j]; } + } + } + // when hash table entry is too long, delete half the entries + if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) { + STBIW_MEMMOVE(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality); + stbiw__sbn(hash_table[h]) = quality; + } + stbiw__sbpush(hash_table[h],data+i); + + if (bestloc) { + // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal + h = stbiw__zhash(data+i+1)&(stbiw__ZHASH-1); + hlist = hash_table[h]; + n = stbiw__sbcount(hlist); + for (j=0; j < n; ++j) { + if (hlist[j]-data > i-32767) { + int e = stbiw__zlib_countm(hlist[j], data+i+1, data_len-i-1); + if (e > best) { // if next match is better, bail on current match + bestloc = NULL; + break; + } + } + } + } + + if (bestloc) { + int d = (int) (data+i - bestloc); // distance back + STBIW_ASSERT(d <= 32767 && best <= 258); + for (j=0; best > lengthc[j+1]-1; ++j); + stbiw__zlib_huff(j+257); + if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]); + for (j=0; d > distc[j+1]-1; ++j); + stbiw__zlib_add(stbiw__zlib_bitrev(j,5),5); + if (disteb[j]) stbiw__zlib_add(d - distc[j], disteb[j]); + i += best; + } else { + stbiw__zlib_huffb(data[i]); + ++i; + } + } + // write out final bytes + for (;i < data_len; ++i) + stbiw__zlib_huffb(data[i]); + stbiw__zlib_huff(256); // end of block + // pad with 0 bits to byte boundary + while (bitcount) + stbiw__zlib_add(0,1); + + for (i=0; i < stbiw__ZHASH; ++i) + (void) stbiw__sbfree(hash_table[i]); + STBIW_FREE(hash_table); + + { + // compute adler32 on input + unsigned int s1=1, s2=0; + int blocklen = (int) (data_len % 5552); + j=0; + while (j < data_len) { + for (i=0; i < blocklen; ++i) { s1 += data[j+i]; s2 += s1; } + s1 %= 65521; s2 %= 65521; + j += blocklen; + blocklen = 5552; + } + stbiw__sbpush(out, STBIW_UCHAR(s2 >> 8)); + stbiw__sbpush(out, STBIW_UCHAR(s2)); + stbiw__sbpush(out, STBIW_UCHAR(s1 >> 8)); + stbiw__sbpush(out, STBIW_UCHAR(s1)); + } + *out_len = stbiw__sbn(out); + // make returned pointer freeable + STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len); + return (unsigned char *) stbiw__sbraw(out); +#endif // STBIW_ZLIB_COMPRESS +} + +static unsigned int stbiw__crc32(unsigned char *buffer, int len) +{ +#ifdef STBIW_CRC32 + return STBIW_CRC32(buffer, len); +#else + static unsigned int crc_table[256] = + { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0eDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D + }; + + unsigned int crc = ~0u; + int i; + for (i=0; i < len; ++i) + crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)]; + return ~crc; +#endif +} + +#define stbiw__wpng4(o,a,b,c,d) ((o)[0]=STBIW_UCHAR(a),(o)[1]=STBIW_UCHAR(b),(o)[2]=STBIW_UCHAR(c),(o)[3]=STBIW_UCHAR(d),(o)+=4) +#define stbiw__wp32(data,v) stbiw__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v)); +#define stbiw__wptag(data,s) stbiw__wpng4(data, s[0],s[1],s[2],s[3]) + +static void stbiw__wpcrc(unsigned char **data, int len) +{ + unsigned int crc = stbiw__crc32(*data - len - 4, len+4); + stbiw__wp32(*data, crc); +} + +static unsigned char stbiw__paeth(int a, int b, int c) +{ + int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c); + if (pa <= pb && pa <= pc) return STBIW_UCHAR(a); + if (pb <= pc) return STBIW_UCHAR(b); + return STBIW_UCHAR(c); +} + +// @OPTIMIZE: provide an option that always forces left-predict or paeth predict +static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int width, int height, int y, int n, int filter_type, signed char *line_buffer) +{ + static int mapping[] = { 0,1,2,3,4 }; + static int firstmap[] = { 0,1,0,5,6 }; + int *mymap = (y != 0) ? mapping : firstmap; + int i; + int type = mymap[filter_type]; + unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y); + int signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes; + + if (type==0) { + memcpy(line_buffer, z, width*n); + return; + } + + // first loop isn't optimized since it's just one pixel + for (i = 0; i < n; ++i) { + switch (type) { + case 1: line_buffer[i] = z[i]; break; + case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break; + case 3: line_buffer[i] = z[i] - (z[i-signed_stride]>>1); break; + case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-signed_stride],0)); break; + case 5: line_buffer[i] = z[i]; break; + case 6: line_buffer[i] = z[i]; break; + } + } + switch (type) { + case 1: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-n]; break; + case 2: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-signed_stride]; break; + case 3: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - ((z[i-n] + z[i-signed_stride])>>1); break; + case 4: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-signed_stride], z[i-signed_stride-n]); break; + case 5: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - (z[i-n]>>1); break; + case 6: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break; + } +} + +STBIWDEF unsigned char *stbi_write_png_to_mem(const unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len) +{ + int force_filter = stbi_write_force_png_filter; + int ctype[5] = { -1, 0, 4, 2, 6 }; + unsigned char sig[8] = { 137,80,78,71,13,10,26,10 }; + unsigned char *out,*o, *filt, *zlib; + signed char *line_buffer; + int j,zlen; + + if (stride_bytes == 0) + stride_bytes = x * n; + + if (force_filter >= 5) { + force_filter = -1; + } + + filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0; + line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; } + for (j=0; j < y; ++j) { + int filter_type; + if (force_filter > -1) { + filter_type = force_filter; + stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, force_filter, line_buffer); + } else { // Estimate the best filter by running through all of them: + int best_filter = 0, best_filter_val = 0x7fffffff, est, i; + for (filter_type = 0; filter_type < 5; filter_type++) { + stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, filter_type, line_buffer); + + // Estimate the entropy of the line using this filter; the less, the better. + est = 0; + for (i = 0; i < x*n; ++i) { + est += abs((signed char) line_buffer[i]); + } + if (est < best_filter_val) { + best_filter_val = est; + best_filter = filter_type; + } + } + if (filter_type != best_filter) { // If the last iteration already got us the best filter, don't redo it + stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, best_filter, line_buffer); + filter_type = best_filter; + } + } + // when we get here, filter_type contains the filter type, and line_buffer contains the data + filt[j*(x*n+1)] = (unsigned char) filter_type; + STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n); + } + STBIW_FREE(line_buffer); + zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, stbi_write_png_compression_level); + STBIW_FREE(filt); + if (!zlib) return 0; + + // each tag requires 12 bytes of overhead + out = (unsigned char *) STBIW_MALLOC(8 + 12+13 + 12+zlen + 12); + if (!out) return 0; + *out_len = 8 + 12+13 + 12+zlen + 12; + + o=out; + STBIW_MEMMOVE(o,sig,8); o+= 8; + stbiw__wp32(o, 13); // header length + stbiw__wptag(o, "IHDR"); + stbiw__wp32(o, x); + stbiw__wp32(o, y); + *o++ = 8; + *o++ = STBIW_UCHAR(ctype[n]); + *o++ = 0; + *o++ = 0; + *o++ = 0; + stbiw__wpcrc(&o,13); + + stbiw__wp32(o, zlen); + stbiw__wptag(o, "IDAT"); + STBIW_MEMMOVE(o, zlib, zlen); + o += zlen; + STBIW_FREE(zlib); + stbiw__wpcrc(&o, zlen); + + stbiw__wp32(o,0); + stbiw__wptag(o, "IEND"); + stbiw__wpcrc(&o,0); + + STBIW_ASSERT(o == out + *out_len); + + return out; +} + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes) +{ + FILE *f; + int len; + unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len); + if (png == NULL) return 0; + + f = stbiw__fopen(filename, "wb"); + if (!f) { STBIW_FREE(png); return 0; } + fwrite(png, 1, len, f); + fclose(f); + STBIW_FREE(png); + return 1; +} +#endif + +STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int stride_bytes) +{ + int len; + unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len); + if (png == NULL) return 0; + func(context, png, len); + STBIW_FREE(png); + return 1; +} + + +/* *************************************************************************** + * + * JPEG writer + * + * This is based on Jon Olick's jo_jpeg.cpp: + * public domain Simple, Minimalistic JPEG writer - http://www.jonolick.com/code.html + */ + +static const unsigned char stbiw__jpg_ZigZag[] = { 0,1,5,6,14,15,27,28,2,4,7,13,16,26,29,42,3,8,12,17,25,30,41,43,9,11,18, + 24,31,40,44,53,10,19,23,32,39,45,52,54,20,22,33,38,46,51,55,60,21,34,37,47,50,56,59,61,35,36,48,49,57,58,62,63 }; + +static void stbiw__jpg_writeBits(stbi__write_context *s, int *bitBufP, int *bitCntP, const unsigned short *bs) { + int bitBuf = *bitBufP, bitCnt = *bitCntP; + bitCnt += bs[1]; + bitBuf |= bs[0] << (24 - bitCnt); + while(bitCnt >= 8) { + unsigned char c = (bitBuf >> 16) & 255; + stbiw__putc(s, c); + if(c == 255) { + stbiw__putc(s, 0); + } + bitBuf <<= 8; + bitCnt -= 8; + } + *bitBufP = bitBuf; + *bitCntP = bitCnt; +} + +static void stbiw__jpg_DCT(float *d0p, float *d1p, float *d2p, float *d3p, float *d4p, float *d5p, float *d6p, float *d7p) { + float d0 = *d0p, d1 = *d1p, d2 = *d2p, d3 = *d3p, d4 = *d4p, d5 = *d5p, d6 = *d6p, d7 = *d7p; + float z1, z2, z3, z4, z5, z11, z13; + + float tmp0 = d0 + d7; + float tmp7 = d0 - d7; + float tmp1 = d1 + d6; + float tmp6 = d1 - d6; + float tmp2 = d2 + d5; + float tmp5 = d2 - d5; + float tmp3 = d3 + d4; + float tmp4 = d3 - d4; + + // Even part + float tmp10 = tmp0 + tmp3; // phase 2 + float tmp13 = tmp0 - tmp3; + float tmp11 = tmp1 + tmp2; + float tmp12 = tmp1 - tmp2; + + d0 = tmp10 + tmp11; // phase 3 + d4 = tmp10 - tmp11; + + z1 = (tmp12 + tmp13) * 0.707106781f; // c4 + d2 = tmp13 + z1; // phase 5 + d6 = tmp13 - z1; + + // Odd part + tmp10 = tmp4 + tmp5; // phase 2 + tmp11 = tmp5 + tmp6; + tmp12 = tmp6 + tmp7; + + // The rotator is modified from fig 4-8 to avoid extra negations. + z5 = (tmp10 - tmp12) * 0.382683433f; // c6 + z2 = tmp10 * 0.541196100f + z5; // c2-c6 + z4 = tmp12 * 1.306562965f + z5; // c2+c6 + z3 = tmp11 * 0.707106781f; // c4 + + z11 = tmp7 + z3; // phase 5 + z13 = tmp7 - z3; + + *d5p = z13 + z2; // phase 6 + *d3p = z13 - z2; + *d1p = z11 + z4; + *d7p = z11 - z4; + + *d0p = d0; *d2p = d2; *d4p = d4; *d6p = d6; +} + +static void stbiw__jpg_calcBits(int val, unsigned short bits[2]) { + int tmp1 = val < 0 ? -val : val; + val = val < 0 ? val-1 : val; + bits[1] = 1; + while(tmp1 >>= 1) { + ++bits[1]; + } + bits[0] = val & ((1<0)&&(DU[end0pos]==0); --end0pos) { + } + // end0pos = first element in reverse order !=0 + if(end0pos == 0) { + stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB); + return DU[0]; + } + for(i = 1; i <= end0pos; ++i) { + int startpos = i; + int nrzeroes; + unsigned short bits[2]; + for (; DU[i]==0 && i<=end0pos; ++i) { + } + nrzeroes = i-startpos; + if ( nrzeroes >= 16 ) { + int lng = nrzeroes>>4; + int nrmarker; + for (nrmarker=1; nrmarker <= lng; ++nrmarker) + stbiw__jpg_writeBits(s, bitBuf, bitCnt, M16zeroes); + nrzeroes &= 15; + } + stbiw__jpg_calcBits(DU[i], bits); + stbiw__jpg_writeBits(s, bitBuf, bitCnt, HTAC[(nrzeroes<<4)+bits[1]]); + stbiw__jpg_writeBits(s, bitBuf, bitCnt, bits); + } + if(end0pos != 63) { + stbiw__jpg_writeBits(s, bitBuf, bitCnt, EOB); + } + return DU[0]; +} + +static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, int comp, const void* data, int quality) { + // Constants that don't pollute global namespace + static const unsigned char std_dc_luminance_nrcodes[] = {0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0}; + static const unsigned char std_dc_luminance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11}; + static const unsigned char std_ac_luminance_nrcodes[] = {0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d}; + static const unsigned char std_ac_luminance_values[] = { + 0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08, + 0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28, + 0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59, + 0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89, + 0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6, + 0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2, + 0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa + }; + static const unsigned char std_dc_chrominance_nrcodes[] = {0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0}; + static const unsigned char std_dc_chrominance_values[] = {0,1,2,3,4,5,6,7,8,9,10,11}; + static const unsigned char std_ac_chrominance_nrcodes[] = {0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77}; + static const unsigned char std_ac_chrominance_values[] = { + 0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91, + 0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26, + 0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58, + 0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87, + 0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4, + 0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda, + 0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa + }; + // Huffman tables + static const unsigned short YDC_HT[256][2] = { {0,2},{2,3},{3,3},{4,3},{5,3},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9}}; + static const unsigned short UVDC_HT[256][2] = { {0,2},{1,2},{2,2},{6,3},{14,4},{30,5},{62,6},{126,7},{254,8},{510,9},{1022,10},{2046,11}}; + static const unsigned short YAC_HT[256][2] = { + {10,4},{0,2},{1,2},{4,3},{11,4},{26,5},{120,7},{248,8},{1014,10},{65410,16},{65411,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {12,4},{27,5},{121,7},{502,9},{2038,11},{65412,16},{65413,16},{65414,16},{65415,16},{65416,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {28,5},{249,8},{1015,10},{4084,12},{65417,16},{65418,16},{65419,16},{65420,16},{65421,16},{65422,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {58,6},{503,9},{4085,12},{65423,16},{65424,16},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {59,6},{1016,10},{65430,16},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {122,7},{2039,11},{65438,16},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {123,7},{4086,12},{65446,16},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {250,8},{4087,12},{65454,16},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {504,9},{32704,15},{65462,16},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {505,9},{65470,16},{65471,16},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {506,9},{65479,16},{65480,16},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {1017,10},{65488,16},{65489,16},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {1018,10},{65497,16},{65498,16},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {2040,11},{65506,16},{65507,16},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {65515,16},{65516,16},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{0,0},{0,0},{0,0},{0,0},{0,0}, + {2041,11},{65525,16},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0} + }; + static const unsigned short UVAC_HT[256][2] = { + {0,2},{1,2},{4,3},{10,4},{24,5},{25,5},{56,6},{120,7},{500,9},{1014,10},{4084,12},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {11,4},{57,6},{246,8},{501,9},{2038,11},{4085,12},{65416,16},{65417,16},{65418,16},{65419,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {26,5},{247,8},{1015,10},{4086,12},{32706,15},{65420,16},{65421,16},{65422,16},{65423,16},{65424,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {27,5},{248,8},{1016,10},{4087,12},{65425,16},{65426,16},{65427,16},{65428,16},{65429,16},{65430,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {58,6},{502,9},{65431,16},{65432,16},{65433,16},{65434,16},{65435,16},{65436,16},{65437,16},{65438,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {59,6},{1017,10},{65439,16},{65440,16},{65441,16},{65442,16},{65443,16},{65444,16},{65445,16},{65446,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {121,7},{2039,11},{65447,16},{65448,16},{65449,16},{65450,16},{65451,16},{65452,16},{65453,16},{65454,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {122,7},{2040,11},{65455,16},{65456,16},{65457,16},{65458,16},{65459,16},{65460,16},{65461,16},{65462,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {249,8},{65463,16},{65464,16},{65465,16},{65466,16},{65467,16},{65468,16},{65469,16},{65470,16},{65471,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {503,9},{65472,16},{65473,16},{65474,16},{65475,16},{65476,16},{65477,16},{65478,16},{65479,16},{65480,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {504,9},{65481,16},{65482,16},{65483,16},{65484,16},{65485,16},{65486,16},{65487,16},{65488,16},{65489,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {505,9},{65490,16},{65491,16},{65492,16},{65493,16},{65494,16},{65495,16},{65496,16},{65497,16},{65498,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {506,9},{65499,16},{65500,16},{65501,16},{65502,16},{65503,16},{65504,16},{65505,16},{65506,16},{65507,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {2041,11},{65508,16},{65509,16},{65510,16},{65511,16},{65512,16},{65513,16},{65514,16},{65515,16},{65516,16},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, + {16352,14},{65517,16},{65518,16},{65519,16},{65520,16},{65521,16},{65522,16},{65523,16},{65524,16},{65525,16},{0,0},{0,0},{0,0},{0,0},{0,0}, + {1018,10},{32707,15},{65526,16},{65527,16},{65528,16},{65529,16},{65530,16},{65531,16},{65532,16},{65533,16},{65534,16},{0,0},{0,0},{0,0},{0,0},{0,0} + }; + static const int YQT[] = {16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,18,22, + 37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99}; + static const int UVQT[] = {17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99, + 99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99}; + static const float aasf[] = { 1.0f * 2.828427125f, 1.387039845f * 2.828427125f, 1.306562965f * 2.828427125f, 1.175875602f * 2.828427125f, + 1.0f * 2.828427125f, 0.785694958f * 2.828427125f, 0.541196100f * 2.828427125f, 0.275899379f * 2.828427125f }; + + int row, col, i, k, subsample; + float fdtbl_Y[64], fdtbl_UV[64]; + unsigned char YTable[64], UVTable[64]; + + if(!data || !width || !height || comp > 4 || comp < 1) { + return 0; + } + + quality = quality ? quality : 90; + subsample = quality <= 90 ? 1 : 0; + quality = quality < 1 ? 1 : quality > 100 ? 100 : quality; + quality = quality < 50 ? 5000 / quality : 200 - quality * 2; + + for(i = 0; i < 64; ++i) { + int uvti, yti = (YQT[i]*quality+50)/100; + YTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (yti < 1 ? 1 : yti > 255 ? 255 : yti); + uvti = (UVQT[i]*quality+50)/100; + UVTable[stbiw__jpg_ZigZag[i]] = (unsigned char) (uvti < 1 ? 1 : uvti > 255 ? 255 : uvti); + } + + for(row = 0, k = 0; row < 8; ++row) { + for(col = 0; col < 8; ++col, ++k) { + fdtbl_Y[k] = 1 / (YTable [stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]); + fdtbl_UV[k] = 1 / (UVTable[stbiw__jpg_ZigZag[k]] * aasf[row] * aasf[col]); + } + } + + // Write Headers + { + static const unsigned char head0[] = { 0xFF,0xD8,0xFF,0xE0,0,0x10,'J','F','I','F',0,1,1,0,0,1,0,1,0,0,0xFF,0xDB,0,0x84,0 }; + static const unsigned char head2[] = { 0xFF,0xDA,0,0xC,3,1,0,2,0x11,3,0x11,0,0x3F,0 }; + const unsigned char head1[] = { 0xFF,0xC0,0,0x11,8,(unsigned char)(height>>8),STBIW_UCHAR(height),(unsigned char)(width>>8),STBIW_UCHAR(width), + 3,1,(unsigned char)(subsample?0x22:0x11),0,2,0x11,1,3,0x11,1,0xFF,0xC4,0x01,0xA2,0 }; + s->func(s->context, (void*)head0, sizeof(head0)); + s->func(s->context, (void*)YTable, sizeof(YTable)); + stbiw__putc(s, 1); + s->func(s->context, UVTable, sizeof(UVTable)); + s->func(s->context, (void*)head1, sizeof(head1)); + s->func(s->context, (void*)(std_dc_luminance_nrcodes+1), sizeof(std_dc_luminance_nrcodes)-1); + s->func(s->context, (void*)std_dc_luminance_values, sizeof(std_dc_luminance_values)); + stbiw__putc(s, 0x10); // HTYACinfo + s->func(s->context, (void*)(std_ac_luminance_nrcodes+1), sizeof(std_ac_luminance_nrcodes)-1); + s->func(s->context, (void*)std_ac_luminance_values, sizeof(std_ac_luminance_values)); + stbiw__putc(s, 1); // HTUDCinfo + s->func(s->context, (void*)(std_dc_chrominance_nrcodes+1), sizeof(std_dc_chrominance_nrcodes)-1); + s->func(s->context, (void*)std_dc_chrominance_values, sizeof(std_dc_chrominance_values)); + stbiw__putc(s, 0x11); // HTUACinfo + s->func(s->context, (void*)(std_ac_chrominance_nrcodes+1), sizeof(std_ac_chrominance_nrcodes)-1); + s->func(s->context, (void*)std_ac_chrominance_values, sizeof(std_ac_chrominance_values)); + s->func(s->context, (void*)head2, sizeof(head2)); + } + + // Encode 8x8 macroblocks + { + static const unsigned short fillBits[] = {0x7F, 7}; + int DCY=0, DCU=0, DCV=0; + int bitBuf=0, bitCnt=0; + // comp == 2 is grey+alpha (alpha is ignored) + int ofsG = comp > 2 ? 1 : 0, ofsB = comp > 2 ? 2 : 0; + const unsigned char *dataR = (const unsigned char *)data; + const unsigned char *dataG = dataR + ofsG; + const unsigned char *dataB = dataR + ofsB; + int x, y, pos; + if(subsample) { + for(y = 0; y < height; y += 16) { + for(x = 0; x < width; x += 16) { + float Y[256], U[256], V[256]; + for(row = y, pos = 0; row < y+16; ++row) { + // row >= height => use last input row + int clamped_row = (row < height) ? row : height - 1; + int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp; + for(col = x; col < x+16; ++col, ++pos) { + // if col >= width => use pixel from last input column + int p = base_p + ((col < width) ? col : (width-1))*comp; + float r = dataR[p], g = dataG[p], b = dataB[p]; + Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128; + U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b; + V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b; + } + } + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+0, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+8, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+128, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y+136, 16, fdtbl_Y, DCY, YDC_HT, YAC_HT); + + // subsample U,V + { + float subU[64], subV[64]; + int yy, xx; + for(yy = 0, pos = 0; yy < 8; ++yy) { + for(xx = 0; xx < 8; ++xx, ++pos) { + int j = yy*32+xx*2; + subU[pos] = (U[j+0] + U[j+1] + U[j+16] + U[j+17]) * 0.25f; + subV[pos] = (V[j+0] + V[j+1] + V[j+16] + V[j+17]) * 0.25f; + } + } + DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subU, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); + DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, subV, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); + } + } + } + } else { + for(y = 0; y < height; y += 8) { + for(x = 0; x < width; x += 8) { + float Y[64], U[64], V[64]; + for(row = y, pos = 0; row < y+8; ++row) { + // row >= height => use last input row + int clamped_row = (row < height) ? row : height - 1; + int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp; + for(col = x; col < x+8; ++col, ++pos) { + // if col >= width => use pixel from last input column + int p = base_p + ((col < width) ? col : (width-1))*comp; + float r = dataR[p], g = dataG[p], b = dataB[p]; + Y[pos]= +0.29900f*r + 0.58700f*g + 0.11400f*b - 128; + U[pos]= -0.16874f*r - 0.33126f*g + 0.50000f*b; + V[pos]= +0.50000f*r - 0.41869f*g - 0.08131f*b; + } + } + + DCY = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, Y, 8, fdtbl_Y, DCY, YDC_HT, YAC_HT); + DCU = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, U, 8, fdtbl_UV, DCU, UVDC_HT, UVAC_HT); + DCV = stbiw__jpg_processDU(s, &bitBuf, &bitCnt, V, 8, fdtbl_UV, DCV, UVDC_HT, UVAC_HT); + } + } + } + + // Do the bit alignment of the EOI marker + stbiw__jpg_writeBits(s, &bitBuf, &bitCnt, fillBits); + } + + // EOI + stbiw__putc(s, 0xFF); + stbiw__putc(s, 0xD9); + + return 1; +} + +STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality) +{ + stbi__write_context s; + stbi__start_write_callbacks(&s, func, context); + return stbi_write_jpg_core(&s, x, y, comp, (void *) data, quality); +} + + +#ifndef STBI_WRITE_NO_STDIO +STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality) +{ + stbi__write_context s; + if (stbi__start_write_file(&s,filename)) { + int r = stbi_write_jpg_core(&s, x, y, comp, data, quality); + stbi__end_write_file(&s); + return r; + } else + return 0; +} +#endif + +#endif // STB_IMAGE_WRITE_IMPLEMENTATION + +/* Revision history + 1.14 (2020-02-02) updated JPEG writer to downsample chroma channels + 1.13 + 1.12 + 1.11 (2019-08-11) + + 1.10 (2019-02-07) + support utf8 filenames in Windows; fix warnings and platform ifdefs + 1.09 (2018-02-11) + fix typo in zlib quality API, improve STB_I_W_STATIC in C++ + 1.08 (2018-01-29) + add stbi__flip_vertically_on_write, external zlib, zlib quality, choose PNG filter + 1.07 (2017-07-24) + doc fix + 1.06 (2017-07-23) + writing JPEG (using Jon Olick's code) + 1.05 ??? + 1.04 (2017-03-03) + monochrome BMP expansion + 1.03 ??? + 1.02 (2016-04-02) + avoid allocating large structures on the stack + 1.01 (2016-01-16) + STBIW_REALLOC_SIZED: support allocators with no realloc support + avoid race-condition in crc initialization + minor compile issues + 1.00 (2015-09-14) + installable file IO function + 0.99 (2015-09-13) + warning fixes; TGA rle support + 0.98 (2015-04-08) + added STBIW_MALLOC, STBIW_ASSERT etc + 0.97 (2015-01-18) + fixed HDR asserts, rewrote HDR rle logic + 0.96 (2015-01-17) + add HDR output + fix monochrome BMP + 0.95 (2014-08-17) + add monochrome TGA output + 0.94 (2014-05-31) + rename private functions to avoid conflicts with stb_image.h + 0.93 (2014-05-27) + warning fixes + 0.92 (2010-08-01) + casts to unsigned char to fix warnings + 0.91 (2010-07-17) + first public release + 0.90 first internal release +*/ + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/Makefile new file mode 100644 index 00000000..1a7859d5 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/Makefile @@ -0,0 +1,105 @@ +SHELL = /bin/bash +SDK_VER? := 64bit + +ifeq ($(CHIP_ARCH), MARS) + CHIP_ARCH:=CV181X +else ifeq ($(CHIP_ARCH), PHOBOS) + CHIP_ARCH:=CV180X +endif + +ifeq ($(PARAM_FILE), ) + PARAM_FILE:=Makefile.param + include $(PARAM_FILE) +endif + +CHIP_DIR := $(MW_PATH)/chips/$(shell echo $(CHIP_ARCH) | tr A-Z a-z) + +ifeq ($(DESTDIR),) + DESTDIR := $(shell pwd)/install +endif + +define package_mw + @install -d $(1) + @tar -c --exclude='chips' --exclude='modules' --exclude='$(1)' --exclude='.git' --exclude='tool' --exclude='component/panel/cv1835/customer' -f - . | (cd $(1); tar xf -) + @rm $(1)/3rdparty/gtest -r + @rm $(1)/sample/ -r + @make -C sample/ clean + @cp sample $(1)/sample -r +endef + +.PHONY: clean all module component sample install uninstall package 3rdparty + +all: prepare 3rdparty module component sample + +module: prepare 3rdparty + @make -C modules/ + +prepare: + @if [ -d mod_tmp ]; then mv mod_tmp modules; fi; + @mkdir -p include/isp + @cp -rf modules/isp/include/* include/isp +3rdparty: + @make -C 3rdparty/ + +sample: module component + @mv modules mod_tmp + @make -C sample/ || mv mod_tmp modules + @mv mod_tmp modules + +component: + @make -C component/isp/ all + +ifneq ($(SUBTYPE), fpga) +install: + @mkdir -p $(DESTDIR)/usr/bin + @mkdir -p $(DESTDIR)/usr/lib/3rd +ifneq ($(FLASH_SIZE_SHRINK),y) + # copy sample_xxx + @cp -f sample/mipi_tx/sample_dsi $(DESTDIR)/usr/bin + @cp -f sample/vio/sample_vio $(DESTDIR)/usr/bin + @cp -f sample/sensor_test/sensor_test $(DESTDIR)/usr/bin + @cp -f sample/audio/sample_audio $(DESTDIR)/usr/bin + #@cp -f sample/cipher/sample_cipher $(DESTDIR)/usr/bin + #@cp -f sample/cvg/sample_cvg $(DESTDIR)/usr/bin + @cp -f sample/venc/sample_venc $(DESTDIR)/usr/bin + @cp -f sample/venc/sample_vcodec $(DESTDIR)/usr/bin + @cp -f sample/vdec/sample_vdec $(DESTDIR)/usr/bin +endif + +ifneq ($(FLASH_SIZE_SHRINK),y) + # copy venc + #@cp -f modules/venc/vc_lib/bin/cvi_h265_enc_test $(DESTDIR)/usr/bin + #@cp -f modules/venc/vc_lib/bin/cvi_h265_dec $(DESTDIR)/usr/bin + #@cp -f modules/venc/vc_lib/bin/cvi_h264_dec $(DESTDIR)/usr/bin + #@cp -f modules/venc/vc_lib/bin/cvi_jpg_codec $(DESTDIR)/usr/bin +endif + +ifneq ($(FLASH_SIZE_SHRINK),y) + # copy audio libs and elf + @cp -f sample/audio/sample_audio* $(DESTDIR)/usr/bin + @if [ -e "sample/audio/cvi_mp3player" ]; then cp -f sample/audio/cvi_mp3player $(DESTDIR)/usr/bin; fi +endif + + # copy mw lib + @cp -a lib/*.so* $(DESTDIR)/usr/lib + @cp -a lib/3rd/*.so* $(DESTDIR)/usr/lib/3rd + +uninstall: + @rm $(DESTDIR) -rf + +package: + $(call package_mw,tmp) + @install -d $(DESTDIR) + @tar fcz $(DESTDIR)/mw.tar.gz -C tmp . + @echo $(KERNEL_INC) + @tar fcz $(DESTDIR)/kernel_header.tar.gz -C $(KERNEL_INC) ./ + @rm tmp -r + @echo "package done" +endif +clean: + @if [ -d mod_tmp ]; then mv mod_tmp modules; fi; + @rm -rf include/isp + @make -C modules/ clean + @make -C 3rdparty/ clean + @make -C sample/ clean + @make -C component/isp/ clean diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/Makefile.param b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/Makefile.param new file mode 100644 index 00000000..e03d73d1 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/Makefile.param @@ -0,0 +1,194 @@ +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 += -mcpu=c906fdv -march=rv64imafdcv0p7xthead -mcmodel=medany -mabi=lp64d +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 += -mcpu=c906fdv -march=rv64imafdcv0p7xthead -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 + +ISP_LIB += -lisp_algo +ISP_OBJ += $(MW_LIB)/libisp_algo.a + +## 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 +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 +endif + +ifeq ($(CONFIG_DISABLE_PQBIN_JSON), y) +CFLAGS += -DDISABLE_PQBIN_JSON +endif + +CFLAGS += -DARCH_$(CHIP_ARCH) + +ifeq ("$(CHIP_ARCH)", "SG200X") +CFLAGS += -D__SOC_MARS__ +endif +ifeq ("$(CHIP_ARCH)", "CV181X") +CFLAGS += -D__SOC_MARS__ +endif +ifeq ("$(CHIP_ARCH)", "CV180X") +CFLAGS += -D__SOC_PHOBOS__ +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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/Makefile new file mode 100644 index 00000000..78c11e75 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/Makefile @@ -0,0 +1,16 @@ +SHELL = /bin/bash + +include $(BUILD_PATH)/.config +include sensor.mk + +chip_arch = $(shell echo $(CHIP_ARCH) | tr A-Z a-z) + +all: + pushd sensor/$(chip_arch) && \ + $(MAKE) all && \ + popd; + +clean: + pushd sensor/$(chip_arch) && \ + $(MAKE) clean && \ + popd; diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor.mk b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor.mk new file mode 100644 index 00000000..ed3b282f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor.mk @@ -0,0 +1,135 @@ +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_IMGDS_MIS2008) += imgds_mis2008 +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_SC3336P) += sms_sc3336p +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_TECHPOINT_TP2863) += techpoint_tp2863 +sensor-$(CONFIG_SENSOR_VIVO_MCS369) += vivo_mcs369 +sensor-$(CONFIG_SENSOR_VIVO_MCS369Q) += vivo_mcs369q +sensor-$(CONFIG_SENSOR_VIVO_MM308M2) += vivo_mm308m2 +sensor-$(CONFIG_SENSOR_TECHPOINT_TP2825) += techpoint_tp2825 +else +sensor-$(CONFIG_SENSOR_BRIGATES_BG0808) += brigates_bg0808 +sensor-$(CONFIG_SENSOR_CVSENS_CV4001) += cvsens_cv4001 +sensor-$(CONFIG_SENSOR_BYD_BF2253L) += byd_bf2253l +sensor-$(CONFIG_SENSOR_GCORE_GC02M1) += gcore_gc02m1 +sensor-$(CONFIG_SENSOR_GCORE_GC0312) += gcore_gc0312 +sensor-$(CONFIG_SENSOR_GCORE_GC0329) += gcore_gc0329 +sensor-$(CONFIG_SENSOR_GCORE_GC1054) += gcore_gc1054 +sensor-$(CONFIG_SENSOR_GCORE_GC1084) += gcore_gc1084 +sensor-$(CONFIG_SENSOR_GCORE_GC1084_SLAVE) += gcore_gc1084_slave +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_GC2083) += gcore_gc2083 +sensor-$(CONFIG_SENSOR_GCORE_GC2145) += gcore_gc2145 +sensor-$(CONFIG_SENSOR_GCORE_GC4023) += gcore_gc4023 +sensor-$(CONFIG_SENSOR_GCORE_GC4653) += gcore_gc4653 +sensor-$(CONFIG_SENSOR_IMGDS_MIS2008) += imgds_mis2008 +sensor-$(CONFIG_SENSOR_IMGDS_MIS2008_1L) += imgds_mis2008_1L +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_OV5647) += ov_ov5647 +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_SC035HGS_1L) += sms_sc035hgs_1L +sensor-$(CONFIG_SENSOR_SMS_SC1336_1L) += sms_sc1336_1L +sensor-$(CONFIG_SENSOR_SMS_SC1346_1L) += sms_sc1346_1L +sensor-$(CONFIG_SENSOR_SMS_SC1346_1L_SLAVE) += sms_sc1346_1L_slave +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_SC3336P) += sms_sc3336p +sensor-$(CONFIG_SENSOR_SMS_SC2331_1L) += sms_sc2331_1L +sensor-$(CONFIG_SENSOR_SMS_SC2331_1L_SLAVE) += sms_sc2331_1L_slave +sensor-$(CONFIG_SENSOR_SMS_SC2331_1L_SLAVE1) += sms_sc2331_1L_slave1 +sensor-$(CONFIG_SENSOR_SMS_SC2335) += sms_sc2335 +sensor-$(CONFIG_SENSOR_SMS_SC2336) += sms_sc2336 +sensor-$(CONFIG_SENSOR_SMS_SC2336_SLAVE) += sms_sc2336_slave +sensor-$(CONFIG_SENSOR_SMS_SC2336_SLAVE1) += sms_sc2336_slave1 +sensor-$(CONFIG_SENSOR_SMS_SC2336_1L) += sms_sc2336_1L +sensor-$(CONFIG_SENSOR_SMS_SC2336P) += sms_sc2336p +sensor-$(CONFIG_SENSOR_SMS_SC2336P_1L) += sms_sc2336p_1L +sensor-$(CONFIG_SENSOR_SMS_SC223A_1L) += sms_sc223a_1L +sensor-$(CONFIG_SENSOR_SMS_SC4336) += sms_sc4336 +sensor-$(CONFIG_SENSOR_SMS_SC4336P) += sms_sc4336p +sensor-$(CONFIG_SENSOR_SMS_SC5336_2L) += sms_sc5336_2L +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_SOI_Q03P) += soi_q03p +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 +sensor-$(CONFIG_SENSOR_TECHPOINT_TP2825) += techpoint_tp2825 +sensor-$(CONFIG_SENSOR_TECHPOINT_TP2863) += techpoint_tp2863 +sensor-$(CONFIG_SENSOR_LONTIUM_LT6911) += lontium_lt6911 +endif diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/cv180x b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/cv180x new file mode 120000 index 00000000..f293db99 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/cv180x @@ -0,0 +1 @@ +cv181x/ \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/cv181x b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/cv181x new file mode 120000 index 00000000..0629d44f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/cv181x @@ -0,0 +1 @@ +sg200x \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/Makefile new file mode 100644 index 00000000..53f97bb2 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/Makefile @@ -0,0 +1,270 @@ +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, ${@}) + +byd_bf2253l: + $(call MAKE_SENSOR, ${@}) + +cvsens_cv4001: + $(call MAKE_SENSOR, ${@}) + +gcore_gc02m1: + $(call MAKE_SENSOR, ${@}) + +gcore_gc0312: + $(call MAKE_SENSOR, ${@}) + +gcore_gc0329: + $(call MAKE_SENSOR, ${@}) + +gcore_gc1054: + $(call MAKE_SENSOR, ${@}) + +gcore_gc1084: + $(call MAKE_SENSOR, ${@}) + +gcore_gc1084_slave: + $(call MAKE_SENSOR, ${@}) + +gcore_gc2053: + $(call MAKE_SENSOR, ${@}) + +gcore_gc2053_slave: + $(call MAKE_SENSOR, ${@}) + +gcore_gc2053_1L: + $(call MAKE_SENSOR, ${@}) + +gcore_gc2083: + $(call MAKE_SENSOR, ${@}) + +gcore_gc2093: + $(call MAKE_SENSOR, ${@}) + +gcore_gc2145: + $(call MAKE_SENSOR, ${@}) + +gcore_gc4023: + $(call MAKE_SENSOR, ${@}) + +gcore_gc4653: + $(call MAKE_SENSOR, ${@}) + +imgds_mis2008: + $(call MAKE_SENSOR, ${@}) + +imgds_mis2008_1L: + $(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_ov5647: + $(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_sc035hgs_1L: + $(call MAKE_SENSOR, ${@}) + +sms_sc1336_1L: + $(call MAKE_SENSOR, ${@}) + +sms_sc1346_1L: + $(call MAKE_SENSOR, ${@}) + +sms_sc1346_1L_slave: + $(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_sc3336p: + $(call MAKE_SENSOR, ${@}) + +sms_sc2331_1L: + $(call MAKE_SENSOR, ${@}) + +sms_sc2331_1L_slave: + $(call MAKE_SENSOR, ${@}) + +sms_sc2331_1L_slave1: + $(call MAKE_SENSOR, ${@}) + +sms_sc2335: + $(call MAKE_SENSOR, ${@}) + +sms_sc2336: + $(call MAKE_SENSOR, ${@}) + +sms_sc2336_slave: + $(call MAKE_SENSOR, ${@}) + +sms_sc2336_slave1: + $(call MAKE_SENSOR, ${@}) + +sms_sc2336_1L: + $(call MAKE_SENSOR, ${@}) + +sms_sc2336p: + $(call MAKE_SENSOR, ${@}) + +sms_sc2336p_1L: + $(call MAKE_SENSOR, ${@}) + +sms_sc223a_1L: + $(call MAKE_SENSOR, ${@}) + +sms_sc4336: + $(call MAKE_SENSOR, ${@}) + +sms_sc4336p: + $(call MAKE_SENSOR, ${@}) + +sms_sc5336_2L: + $(call MAKE_SENSOR, ${@}) + +soi_f23: + $(call MAKE_SENSOR, ${@}) + +soi_f35: + $(call MAKE_SENSOR, ${@}) + +soi_f37p: + $(call MAKE_SENSOR, ${@}) + +soi_q03: + $(call MAKE_SENSOR, ${@}) + +soi_q03p: + $(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, ${@}) + +techpoint_tp2825: + $(call MAKE_SENSOR, ${@}) + +techpoint_tp2863: + $(call MAKE_SENSOR, ${@}) + +lontium_lt6911: + $(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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/Makefile_full b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/Makefile_full new file mode 100644 index 00000000..db3da3c2 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/brigates_bg0808/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/brigates_bg0808/Makefile new file mode 100644 index 00000000..8bc92e24 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/brigates_bg0808/bg0808_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/brigates_bg0808/bg0808_cmos.c new file mode 100644 index 00000000..edc2e21e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/brigates_bg0808/bg0808_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/brigates_bg0808/bg0808_cmos_ex.h new file mode 100644 index 00000000..32027203 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/brigates_bg0808/bg0808_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/brigates_bg0808/bg0808_cmos_param.h new file mode 100644 index 00000000..556578ce --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/brigates_bg0808/bg0808_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/brigates_bg0808/bg0808_sensor_ctl.c new file mode 100644 index 00000000..00e23cd1 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/byd_bf2253l/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/byd_bf2253l/Makefile new file mode 100644 index 00000000..807e96e7 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/byd_bf2253l/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_bf2253l.a +TARGET_SO = $(MW_LIB)/libsns_bf2253l.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/byd_bf2253l/bf2253l_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/byd_bf2253l/bf2253l_cmos.c new file mode 100644 index 00000000..fde5ea6a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/byd_bf2253l/bf2253l_cmos.c @@ -0,0 +1,977 @@ +#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 "bf2253l_cmos_ex.h" +#include "bf2253l_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 BF2253L_ID 35 +#define SENSOR_BF2253L_WIDTH 1600 +#define SENSOR_BF2253L_HEIGHT 1200 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastBF2253L[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define BF2253L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastBF2253L[dev]) +#define BF2253L_SENSOR_SET_CTX(dev, pstCtx) (g_pastBF2253L[dev] = pstCtx) +#define BF2253L_SENSOR_RESET_CTX(dev) (g_pastBF2253L[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunBF2253L_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeBf2253l_MirrorFip[VI_MAX_PIPE_NUM] = {ISP_SNS_NORMAL}; + +CVI_U16 g_au16BF2253L_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16BF2253L_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +BF2253L_STATE_S g_astBF2253L_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); +/*****BF2253L Lines Range*****/ +#define BF2253L_FULL_LINES_MAX (0xFFFF) + +/*****BF2253L Register Address*****/ +#define BF2253L_SHS1_0_ADDR 0x6b +#define BF2253L_SHS1_1_ADDR 0x6c +#define BF2253L_AGAIN0_ADDR 0x6a +#define BF2253L_DGAIN0_ADDR 0x6f + +#define BF2253L_DUMMY_LINE_L_ADDR 0x07 +#define BF2253L_DUMMY_LINE_H_ADDR 0x08 + +#define BF2253L_FLIP_MIRRIR_ADDR 0x00 + +#define BF2253L_RES_IS_1200P(w, h) ((w) <= 1600 && (h) <= 1200) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const BF2253L_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + BF2253L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astBF2253L_mode[pstSnsState->u8ImgMode]; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = BF2253L_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 10); + + 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 * 10 / 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_U32 u32DummyLine; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + BF2253L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astBF2253L_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astBF2253L_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astBF2253L_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case BF2253L_MODE_1200P10: + 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 > BF2253L_FULL_LINES_MAX) ? BF2253L_FULL_LINES_MAX : u32VMAX; + break; + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode); + return CVI_FAILURE; + } + + u32DummyLine = u32VMAX - u32Vts; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_DL_0_ADDR].u32Data = ((u32DummyLine & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_DL_1_ADDR].u32Data = (u32DummyLine & 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 - 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; + + BF2253L_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 & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0xFF)); + } + + 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, 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 +}; + +static struct gain_tbl_info_s AgainInfo[3] = { + { + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 3968, + .idxBase = 16, + .regGain = 0x00, + .regGainFineBase = 0x20, + .regGainFineStep = 1, + }, + { + .gainMax = 8192, + .idxBase = 32, + .regGain = 0x00, + .regGainFineBase = 0x30, + .regGainFineStep = 1, + }, +}; + +static struct gain_tbl_info_s DgainInfo[4] = { + { + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 3968, + .idxBase = 16, + .regGain = 0x00, + .regGainFineBase = 0x20, + .regGainFineStep = 2, + }, + { + .gainMax = 7396, + .idxBase = 32, + .regGain = 0x00, + .regGainFineBase = 0x40, + .regGainFineStep = 4, + }, + { + .gainMax = 15872, + .idxBase = 64, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 8, + }, +}; + +static CVI_U32 Dgain_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 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 = tableSize - 1; + return CVI_SUCCESS; + } + + for (CVI_U32 i = 1; i < tableSize; 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 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; + + BF2253L_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. */ + 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; + } + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + 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; + } + + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0_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 BF2253L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + BF2253L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astBF2253L_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; + + BF2253L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = BF2253L_MODE_1200P10; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astBF2253L_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); + BF2253L_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_aunBF2253L_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 = bf2253l_i2c_addr; + pstI2c_data[i].u32AddrByteNum = bf2253l_addr_byte; + pstI2c_data[i].u32DataByteNum = bf2253l_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 = BF2253L_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = BF2253L_SHS1_1_ADDR; + pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = BF2253L_AGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = BF2253L_DGAIN0_ADDR; + + pstI2c_data[LINEAR_DL_0_ADDR].u32RegAddr = BF2253L_DUMMY_LINE_H_ADDR; + pstI2c_data[LINEAR_DL_1_ADDR].u32RegAddr = BF2253L_DUMMY_LINE_L_ADDR; + pstI2c_data[LINEAR_FLIP_MIRROR_ADDR].u32RegAddr = BF2253L_FLIP_MIRRIR_ADDR; + 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); + BF2253L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 10) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (BF2253L_RES_IS_1200P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = BF2253L_MODE_1200P10; + } 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 BF2253L_MODE_S *pstMode = CVI_NULL; + + BF2253L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = BF2253L_MODE_1200P10; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astBF2253L_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; + + BF2253L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &bf2253l_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astBF2253L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astBF2253L_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 = &bf2253l_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 = bf2253l_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = bf2253l_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 bf2253l_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunBF2253L_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + BF2253L_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)); + + BF2253L_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + BF2253L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + BF2253L_SENSOR_RESET_CTX(ViPipe); +} + +void bf2253l_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 val = 0; + + BF2253L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->bInit == CVI_TRUE && g_aeBf2253l_MirrorFip[ViPipe] != eSnsMirrorFlip) { + val = bf2253l_read_register(ViPipe, BF2253L_FLIP_MIRRIR_ADDR); + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + val &= ~0x0c; + break; + case ISP_SNS_MIRROR: + val |= (1 << 3); + val &= ~(1 << 2); + break; + case ISP_SNS_FLIP: + val |= (1 << 2); + val &= ~(1 << 3); + break; + case ISP_SNS_MIRROR_FLIP: + val |= 0x0c; + break; + default: + return; + } + + //in order to output rggb bayer pattern,dynamic adjust isp raw crop coordinate, + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR_ADDR].u32Data = val; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR_ADDR].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR_ADDR].u8DropFrmNum = 1; + g_aeBf2253l_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +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 = BF2253L_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, BF2253L_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, BF2253L_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, BF2253L_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_au16BF2253L_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16BF2253L_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsBF2253L_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = bf2253l_standby, + .pfnRestart = bf2253l_restart, + .pfnMirrorFlip = bf2253l_mirror_flip, + .pfnWriteReg = bf2253l_write_register, + .pfnReadReg = bf2253l_read_register, + .pfnSetBusInfo = bf2253l_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 = bf2253l_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/byd_bf2253l/bf2253l_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/byd_bf2253l/bf2253l_cmos_ex.h new file mode 100644 index 00000000..e57607dc --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/byd_bf2253l/bf2253l_cmos_ex.h @@ -0,0 +1,84 @@ +#ifndef __BF2253L_CMOS_EX_H_ +#define __BF2253L_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 bf2253l_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_1_ADDR, + LINEAR_AGAIN_0_ADDR, + LINEAR_DGAIN_0_ADDR, + LINEAR_DL_0_ADDR, //dummy line high 8bit + LINEAR_DL_1_ADDR, //dummy line low 8bit + LINEAR_FLIP_MIRROR_ADDR, + LINEAR_REGS_NUM +}; + + +typedef enum _BF2253L_MODE_E { + BF2253L_MODE_1200P10 = 0, + BF2253L_MODE_LINEAR_NUM, + BF2253L_MODE_NUM +} BF2253L_MODE_E; + +typedef struct _BF2253L_STATE_S { + CVI_U32 u32Sexp_MAX; +} BF2253L_STATE_S; + +typedef struct _BF2253L_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]; +} BF2253L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastBF2253L[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunBF2253L_BusInfo[]; +extern CVI_U16 g_au16BF2253L_GainMode[]; +extern CVI_U16 g_au16BF2253L_L2SMode[]; +extern const CVI_U8 bf2253l_i2c_addr; +extern const CVI_U32 bf2253l_addr_byte; +extern const CVI_U32 bf2253l_data_byte; +extern void bf2253l_init(VI_PIPE ViPipe); +extern void bf2253l_exit(VI_PIPE ViPipe); +extern void bf2253l_standby(VI_PIPE ViPipe); +extern void bf2253l_restart(VI_PIPE ViPipe); +extern int bf2253l_write_register(VI_PIPE ViPipe, int addr, int data); +extern int bf2253l_read_register(VI_PIPE ViPipe, int addr); +extern void bf2253l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int bf2253l_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __BF2253L_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/byd_bf2253l/bf2253l_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/byd_bf2253l/bf2253l_cmos_param.h new file mode 100644 index 00000000..c512b264 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/byd_bf2253l/bf2253l_cmos_param.h @@ -0,0 +1,125 @@ +#ifndef __BF2253L_CMOS_PARAM_H_ +#define __BF2253L_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 "bf2253l_cmos_ex.h" + +static const BF2253L_MODE_S g_astBF2253L_mode[BF2253L_MODE_NUM] = { + [BF2253L_MODE_1200P10] = { + .name = "1200p10", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1600, + .u32Height = 1200, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1600, + .u32Height = 1200, + }, + .stMaxSize = { + .u32Width = 1600, + .u32Height = 1200, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 0.51, /* 1125 * 10 / 0xFFFF*/ + .u32HtsDef = 1780, + .u32VtsDef = 1236, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1236 - 6, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 8192, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 16384, + .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 bf2253l_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_400M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 3, -1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 8, + } + }, + .mclk = { + .cam = 1, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __BF2253L_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/byd_bf2253l/bf2253l_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/byd_bf2253l/bf2253l_sensor_ctl.c new file mode 100644 index 00000000..8f83bb9b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/byd_bf2253l/bf2253l_sensor_ctl.c @@ -0,0 +1,281 @@ +#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 "bf2253l_cmos_ex.h" + +static void bf2253l_linear_1200p10_init(VI_PIPE ViPipe); + +const CVI_U8 bf2253l_i2c_addr = 0x6e; /* I2C Address of BF2253L */ +const CVI_U32 bf2253l_addr_byte = 1; +const CVI_U32 bf2253l_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int bf2253l_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunBF2253L_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, bf2253l_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 bf2253l_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 bf2253l_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 (bf2253l_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, bf2253l_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, bf2253l_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (bf2253l_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 bf2253l_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 (bf2253l_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + + if (bf2253l_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, bf2253l_addr_byte + bf2253l_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 bf2253l_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) + bf2253l_write_register(ViPipe, addr, data); + } +} + +void bf2253l_standby(VI_PIPE ViPipe) +{ + bf2253l_write_register(ViPipe, 0xe0, 0x01); +} + +void bf2253l_restart(VI_PIPE ViPipe) +{ + bf2253l_write_register(ViPipe, 0xe0, 0x01); + delay_ms(20); + bf2253l_write_register(ViPipe, 0xe0, 0x00); +} + +void bf2253l_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastBF2253L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + bf2253l_write_register(ViPipe, + g_pastBF2253L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastBF2253L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define BF2253L_CHIP_ID_HI_ADDR 0xfc +#define BF2253L_CHIP_ID_LO_ADDR 0xfd +#define BF2253L_CHIP_ID 0x2253 + +int bf2253l_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (bf2253l_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = bf2253l_read_register(ViPipe, BF2253L_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 = bf2253l_read_register(ViPipe, BF2253L_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 != BF2253L_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + return CVI_SUCCESS; +} + + +void bf2253l_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + + bInit = g_pastBF2253L[ViPipe]->bInit; + enWDRMode = g_pastBF2253L[ViPipe]->enWDRMode; + + bf2253l_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_NONE) { + bf2253l_linear_1200p10_init(ViPipe); + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_NONE) { + bf2253l_linear_1200p10_init(ViPipe); + } + } + g_pastBF2253L[ViPipe]->bInit = CVI_TRUE; +} + +void bf2253l_exit(VI_PIPE ViPipe) +{ + bf2253l_i2c_exit(ViPipe); +} + +/* 1200P10 and 1200P25 */ +static void bf2253l_linear_1200p10_init(VI_PIPE ViPipe) +{ + bf2253l_write_register(ViPipe, 0xe1, 0x06); + bf2253l_write_register(ViPipe, 0xe2, 0x06); + bf2253l_write_register(ViPipe, 0xe3, 0x0e); + bf2253l_write_register(ViPipe, 0xe4, 0x40); + bf2253l_write_register(ViPipe, 0xe5, 0x67); + bf2253l_write_register(ViPipe, 0xe6, 0x02); + bf2253l_write_register(ViPipe, 0xe8, 0x84); + bf2253l_write_register(ViPipe, 0x01, 0x14); + bf2253l_write_register(ViPipe, 0x03, 0x98); + bf2253l_write_register(ViPipe, 0x27, 0x21); + bf2253l_write_register(ViPipe, 0x29, 0x20); + bf2253l_write_register(ViPipe, 0x59, 0x10); + bf2253l_write_register(ViPipe, 0x5a, 0x10); + bf2253l_write_register(ViPipe, 0x5c, 0x11); + bf2253l_write_register(ViPipe, 0x5d, 0x73); + bf2253l_write_register(ViPipe, 0x6a, 0x2f); + bf2253l_write_register(ViPipe, 0x6b, 0x0e); + bf2253l_write_register(ViPipe, 0x6c, 0x7e); + bf2253l_write_register(ViPipe, 0x6f, 0x10); + bf2253l_write_register(ViPipe, 0x70, 0x08); + bf2253l_write_register(ViPipe, 0x71, 0x05); + bf2253l_write_register(ViPipe, 0x72, 0x10); + bf2253l_write_register(ViPipe, 0x73, 0x08); + bf2253l_write_register(ViPipe, 0x74, 0x05); + bf2253l_write_register(ViPipe, 0x75, 0x06); + bf2253l_write_register(ViPipe, 0x76, 0x20); + bf2253l_write_register(ViPipe, 0x77, 0x03); + bf2253l_write_register(ViPipe, 0x78, 0x0e); + bf2253l_write_register(ViPipe, 0x79, 0x08); + bf2253l_write_register(ViPipe, 0xe0, 0x00); + bf2253l_default_reg_init(ViPipe); + + printf("ViPipe:%d,===BF2253L 1200P 10fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/cvsens_cv4001/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/cvsens_cv4001/Makefile new file mode 100644 index 00000000..a7020a5f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/cvsens_cv4001/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_cv4001.a +TARGET_SO = $(MW_LIB)/libsns_cv4001.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/cvsens_cv4001/cv4001_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/cvsens_cv4001/cv4001_cmos.c new file mode 100644 index 00000000..611301b2 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/cvsens_cv4001/cv4001_cmos.c @@ -0,0 +1,1142 @@ +#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 "cv4001_cmos_ex.h" +#include "cv4001_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 CV4001_ID 4001 +#define CV4001_I2C_ADDR_1 0x35 +#define CV4001_I2C_ADDR_2 0x36 +#define CV4001_I2C_ADDR_IS_VALID(addr) ((addr) == CV4001_I2C_ADDR_1 || (addr) == CV4001_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ***************************************************************************/ + +ISP_SNS_STATE_S *g_pastCV4001[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define CV4001_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastCV4001[dev]) +#define CV4001_SENSOR_SET_CTX(dev, pstCtx) (g_pastCV4001[dev] = pstCtx) +#define CV4001_SENSOR_RESET_CTX(dev) (g_pastCV4001[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunCV4001_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 3}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeCV4001_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +CVI_U16 g_au16CV4001_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); +/*****CV4001 Lines Range*****/ +#define CV4001_FULL_LINES_MAX (0xfffff / 2)//liner mode: vts_reg value is double real_vts +#define CV4001_FULL_LINES_MAX_2TO1_WDR (0xfffff / 4)//wdr mode: four + +/*****CV4001 Register Address*****/ +#define CV4001_EXP1_ADDR0 0x3062 //bit[19:16] +#define CV4001_EXP1_ADDR1 0x3061 +#define CV4001_EXP1_ADDR2 0x3060 +#define CV4001_EXP2_ADDR0 0x3066 +#define CV4001_EXP2_ADDR1 0x3065 +#define CV4001_EXP2_ADDR2 0x3064 + +#define CV4001_AGAIN1_ADDR 0x3180 //bit[7:0] +#define CV4001_AGAIN2_ADDR 0x3181 //bit[7:0] + +#define CV4001_DGAIN1_H_ADDR 0x3179 //bit[15:8] +#define CV4001_DGAIN1_L_ADDR 0x3178 //bit[7:0] +#define CV4001_DGAIN2_H_ADDR 0x317B //bit[15:8] +#define CV4001_DGAIN2_L_ADDR 0x317A //bit[7:0] + +#define CV4001_VTS_ADDR0 0x302A //bit[19:16] +#define CV4001_VTS_ADDR1 0x3029 +#define CV4001_VTS_ADDR2 0x3028 + +#define CV4001_FLIP_MIRROR_ADDR 0x3034 + +#define CV4001_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 CV4001_MODE_S *pstMode; + + CVI_U32 FpsMax; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astCV4001_mode[pstSnsState->u8ImgMode]; + FpsMax = g_astCV4001_mode[pstSnsState->u8ImgMode].f32MaxFps; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = (pstSnsState->enWDRMode == WDR_MODE_NONE) ? + CV4001_FULL_LINES_MAX : CV4001_FULL_LINES_MAX_2TO1_WDR; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * FpsMax); + + 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 * FpsMax / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + + 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->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].u32Max; + 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] : pstMode->stExp[0].u16Def; + + 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->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? + g_au32InitExposure[ViPipe] : pstMode->stExp[0].u16Def; + + 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; + } + 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; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + u32Vts = g_astCV4001_mode[pstSnsState->u8ImgMode].u32VtsDef; + f32MaxFps = g_astCV4001_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astCV4001_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 > CV4001_FULL_LINES_MAX) ? + CV4001_FULL_LINES_MAX : u32VMAX; + pstSnsRegsInfo->astI2cData[LINEAR_VTS_0].u32Data = (((u32VMAX * 2) & 0xFF0000) >> 16); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_1].u32Data = (((u32VMAX * 2) & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_2].u32Data = ((u32VMAX * 2) & 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 > CV4001_FULL_LINES_MAX_2TO1_WDR) ? + CV4001_FULL_LINES_MAX_2TO1_WDR : u32VMAX; + pstSnsRegsInfo->astI2cData[WDR2_VTS_0].u32Data = (((u32VMAX * 4) & 0xFF0000) >> 16); + pstSnsRegsInfo->astI2cData[WDR2_VTS_1].u32Data = (((u32VMAX * 4) & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[WDR2_VTS_2].u32Data = ((u32VMAX * 4) & 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; + CVI_S32 Reg_IntTime1; + CVI_S32 Reg_IntTime2; + + CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + Reg_IntTime1 = (pstSnsState->u32FLStd - u32IntTime[0]) * 2; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_0].u32Data = ((Reg_IntTime1 >> 16) & 0x0F); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_1].u32Data = ((Reg_IntTime1 >> 8) & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_2].u32Data = (Reg_IntTime1 & 0xFF); + } else { + /* short exposure */ + pstSnsState->au32WDRIntTime[0] = u32IntTime[0];//? + /* long exposure */ + pstSnsState->au32WDRIntTime[1] = u32IntTime[1]; + + Reg_IntTime1 = (pstSnsState->u32FLStd - u32IntTime[1]) * 4;//u32IntTime[1] long exposure + Reg_IntTime2 = (pstSnsState->u32FLStd - u32IntTime[0]) * 4 + 2;//u32IntTime[0] short exposure + + pstSnsRegsInfo->astI2cData[WDR2_EXP1_0].u32Data = ((Reg_IntTime1 >> 16) & 0x0F); + pstSnsRegsInfo->astI2cData[WDR2_EXP1_1].u32Data = ((Reg_IntTime1 >> 8) & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_EXP1_2].u32Data = (Reg_IntTime1 & 0xFF); + + pstSnsRegsInfo->astI2cData[WDR2_EXP2_0].u32Data = ((Reg_IntTime2 >> 16) & 0x0F); + pstSnsRegsInfo->astI2cData[WDR2_EXP2_1].u32Data = ((Reg_IntTime2 >> 8) & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_EXP2_2].u32Data = (Reg_IntTime2 & 0xFF); + } + + return CVI_SUCCESS; +} + +static CVI_U32 gain_table[242] = { + 1024, 1024, 1024, 1024, 1040, 1040, 1040, 1040, 1056, 1056, + 1056, 1056, 1072, 1072, 1072, 1072, 1088, 1088, 1088, 1104, + 1104, 1104, 1120, 1120, 1120, 1120, 1136, 1136, 1136, 1152, + 1152, 1152, 1168, 1168, 1168, 1184, 1184, 1184, 1200, 1200, + 1200, 1216, 1216, 1216, 1232, 1232, 1248, 1248, 1248, 1264, + 1264, 1264, 1280, 1280, 1296, 1296, 1296, 1312, 1312, 1328, + 1328, 1344, 1344, 1344, 1360, 1360, 1376, 1376, 1392, 1392, + 1408, 1408, 1424, 1424, 1440, 1440, 1456, 1456, 1472, 1472, + 1488, 1488, 1504, 1504, 1520, 1520, 1536, 1536, 1552, 1568, + 1568, 1584, 1584, 1600, 1616, 1616, 1632, 1648, 1648, 1664, + 1680, 1680, 1696, 1712, 1712, 1728, 1744, 1744, 1760, 1776, + 1792, 1808, 1808, 1824, 1840, 1856, 1872, 1872, 1888, 1904, + 1920, 1936, 1952, 1968, 1984, 2000, 2016, 2016, 2048, 2064, + 2080, 2096, 2112, 2128, 2144, 2160, 2176, 2192, 2208, 2240, + 2256, 2272, 2288, 2304, 2336, 2352, 2368, 2400, 2416, 2448, + 2464, 2496, 2512, 2544, 2560, 2592, 2608, 2640, 2672, 2688, + 2720, 2752, 2784, 2816, 2848, 2880, 2912, 2944, 2976, 3008, + 3040, 3072, 3120, 3152, 3184, 3232, 3264, 3312, 3360, 3392, + 3440, 3488, 3536, 3584, 3632, 3680, 3744, 3792, 3840, 3904, + 3968, 4032, 4096, 4160, 4224, 4288, 4368, 4432, 4512, 4592, + 4672, 4752, 4848, 4944, 5040, 5136, 5232, 5344, 5456, 5568, + 5696, 5824, 5952, 6080, 6240, 6384, 6544, 6720, 6896, 7072, + 7280, 7488, 7696, 7936, 8192, 8448, 8736, 9024, 9360, 9696, + 10080, 10480, 10912, 11392, 11904, 12480, 13104, 13792, 14560, 15408, + 16384, 0x3FFFF, +}; + +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); + + CV4001_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 */ + for (i = 0; i < total; i++) { + if ((gain_table[i] <= pu32Again[0]) && (gain_table[i+1] >= pu32Again[0])) { + break; + } + } + + u32Again = i; + u32Dgain = pu32Dgain[0] / 16; + if (u32Dgain < 64) { + u32Dgain = 64; + } + if (u32Dgain > 1024) { + u32Dgain = 1024; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN].u32Data = u32Again; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0xFF); + } else { + pstSnsRegsInfo->astI2cData[WDR2_AGAIN1].u32Data = u32Again; + pstSnsRegsInfo->astI2cData[WDR2_AGAIN2].u32Data = u32Again; + + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_H].u32Data = (u32Dgain >> 8); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN1_L].u32Data = (u32Dgain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_H].u32Data = (u32Dgain >> 8); + pstSnsRegsInfo->astI2cData[WDR2_DGAIN2_L].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); + CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32ShortTimeMinLimit = 1; + /* + * Long exp + Short exp < VTS + */ + u32IntTimeMaxTmp0 = ((pstSnsState->au32FL[1] - 1 - g_astCV4001_mode[pstSnsState->u8ImgMode].u32IspResTime - + pstSnsState->au32WDRIntTime[0]) * 0x40) / DIV_0_TO_1(au32Ratio[0]); + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 1 - g_astCV4001_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_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) +{ + UNUSED(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) +{ + 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) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + UNUSED(ViPipe); + CV4001_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_stIspBlcCalibratio_wdr, 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 CV4001_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astCV4001_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } else { + 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)); + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == CV4001_MODE_2560X1440P15_WDR) + pstSnsState->u8ImgMode = CV4001_MODE_2560X1440P25; + + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astCV4001_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == CV4001_MODE_2560X1440P25) { + pstSnsState->u8ImgMode = CV4001_MODE_2560X1440P15_WDR; + } + + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astCV4001_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_2To1_LINE 1440p 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); + CV4001_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_aunCV4001_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) ? + WDR2_REGS_NUM : LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = cv4001_i2c_addr; + pstI2c_data[i].u32AddrByteNum = cv4001_addr_byte; + pstI2c_data[i].u32DataByteNum = cv4001_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[WDR2_EXP1_0].u32RegAddr = CV4001_EXP1_ADDR0; + pstI2c_data[WDR2_EXP1_1].u32RegAddr = CV4001_EXP1_ADDR1; + pstI2c_data[WDR2_EXP1_2].u32RegAddr = CV4001_EXP1_ADDR2; + pstI2c_data[WDR2_EXP2_0].u32RegAddr = CV4001_EXP2_ADDR0; + pstI2c_data[WDR2_EXP2_1].u32RegAddr = CV4001_EXP2_ADDR1; + pstI2c_data[WDR2_EXP2_2].u32RegAddr = CV4001_EXP2_ADDR2; + pstI2c_data[WDR2_AGAIN1].u32RegAddr = CV4001_AGAIN1_ADDR; + pstI2c_data[WDR2_AGAIN2].u32RegAddr = CV4001_AGAIN2_ADDR; + pstI2c_data[WDR2_DGAIN1_H].u32RegAddr = CV4001_DGAIN1_H_ADDR; + pstI2c_data[WDR2_DGAIN1_L].u32RegAddr = CV4001_DGAIN1_L_ADDR; + pstI2c_data[WDR2_DGAIN2_H].u32RegAddr = CV4001_DGAIN2_H_ADDR; + pstI2c_data[WDR2_DGAIN2_L].u32RegAddr = CV4001_DGAIN2_L_ADDR; + pstI2c_data[WDR2_VTS_0].u32RegAddr = CV4001_VTS_ADDR0; + pstI2c_data[WDR2_VTS_1].u32RegAddr = CV4001_VTS_ADDR1; + pstI2c_data[WDR2_VTS_2].u32RegAddr = CV4001_VTS_ADDR2; + pstI2c_data[WDR2_FLIP_MIRROR].u32RegAddr = CV4001_FLIP_MIRROR_ADDR; + break; + default: + pstI2c_data[LINEAR_EXP_0].u32RegAddr = CV4001_EXP1_ADDR0; + pstI2c_data[LINEAR_EXP_1].u32RegAddr = CV4001_EXP1_ADDR1; + pstI2c_data[LINEAR_EXP_2].u32RegAddr = CV4001_EXP1_ADDR2; + pstI2c_data[LINEAR_AGAIN].u32RegAddr = CV4001_AGAIN1_ADDR; + pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = CV4001_DGAIN1_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = CV4001_DGAIN1_L_ADDR; + pstI2c_data[LINEAR_VTS_0].u32RegAddr = CV4001_VTS_ADDR0; + pstI2c_data[LINEAR_VTS_1].u32RegAddr = CV4001_VTS_ADDR1; + pstI2c_data[LINEAR_VTS_2].u32RegAddr = CV4001_VTS_ADDR2; + pstI2c_data[LINEAR_FLIP_MIRROR].u32RegAddr = CV4001_FLIP_MIRROR_ADDR; + 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]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = CVI_FALSE; + } else { + pstCfg0->snsCfg.astI2cData[WDR2_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); + CV4001_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 (CV4001_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = CV4001_MODE_2560X1440P25; + 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 (CV4001_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = CV4001_MODE_2560X1440P15_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) +{ + CVI_U8 value = 0x0; + CVI_U8 start_x = 4; + CVI_U8 start_y = 4; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_ISP_INFO_S *pstIspCfg0 = CVI_NULL; + + CV4001_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_aeCV4001_MirrorFip[ViPipe] != eSnsMirrorFlip) { + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + value = 0x0; + start_x = 4; + start_y = 4; + break; + case ISP_SNS_MIRROR: + value = 0x1; + start_x = 5; + start_y = 4; + break; + case ISP_SNS_FLIP: + value = 0x2; + start_x = 4; + start_y = 5; + break; + case ISP_SNS_MIRROR_FLIP: + value = 0x3; + start_x = 5; + start_y = 5; + break; + default: + return; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u32Data = value; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u8DropFrmNum = 2; + } else { + start_x = 0; + start_y = 0; + pstSnsRegsInfo->astI2cData[WDR2_FLIP_MIRROR].u32Data = value; + pstSnsRegsInfo->astI2cData[WDR2_FLIP_MIRROR].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[WDR2_FLIP_MIRROR].u8DropFrmNum = 2; + } + g_aeCV4001_MirrorFip[ViPipe] = eSnsMirrorFlip; + pstIspCfg0->img_size[0].stWndRect.s32X = start_x; + pstIspCfg0->img_size[0].stWndRect.s32Y = start_y; + + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = CV4001_MODE_2560X1440P25; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astCV4001_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astCV4001_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astCV4001_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; + + CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &cv4001_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astCV4001_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astCV4001_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; + } + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &cv4001_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 = cv4001_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = cv4001_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 (CV4001_I2C_ADDR_IS_VALID(s32I2cAddr)) + cv4001_i2c_addr = s32I2cAddr; +} + +static CVI_S32 cv4001_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunCV4001_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + CV4001_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)); + + CV4001_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + CV4001_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + CV4001_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 = CV4001_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, CV4001_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, CV4001_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, CV4001_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_au16CV4001_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return cv4001_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsCV4001_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = cv4001_standby, + .pfnRestart = cv4001_restart, + .pfnWriteReg = cv4001_write_register, + .pfnReadReg = cv4001_read_register, + .pfnSetBusInfo = cv4001_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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/cvsens_cv4001/cv4001_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/cvsens_cv4001/cv4001_cmos_ex.h new file mode 100644 index 00000000..610eec99 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/cvsens_cv4001/cv4001_cmos_ex.h @@ -0,0 +1,109 @@ +#ifndef __CV4001_CMOS_EX_H_ +#define __CV4001_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 cv4001_linear_regs_e { + LINEAR_EXP_0, //0x3062 bit[19:16] + LINEAR_EXP_1, //0x3061 + LINEAR_EXP_2, //0x3060 + LINEAR_AGAIN, //0x3180 bit[7:0] + LINEAR_DGAIN_H, //0x3179 bit[15:8] + LINEAR_DGAIN_L, //0x3178 bit[7:0] + LINEAR_VTS_0, //0x302A bit[19:16] + LINEAR_VTS_1, //0x3029 + LINEAR_VTS_2, //0x3028 + LINEAR_FLIP_MIRROR, //0x3034 + LINEAR_REGS_NUM +}; + +enum cv4001_wdr2_regs_e { + WDR2_EXP1_0, + WDR2_EXP1_1, + WDR2_EXP1_2, + WDR2_EXP2_0, + WDR2_EXP2_1, + WDR2_EXP2_2, + WDR2_AGAIN1, + WDR2_AGAIN2, + WDR2_DGAIN1_H, + WDR2_DGAIN1_L, + WDR2_DGAIN2_H, + WDR2_DGAIN2_L, + WDR2_VTS_0, + WDR2_VTS_1, + WDR2_VTS_2, + WDR2_FLIP_MIRROR, + WDR2_REGS_NUM +}; + +typedef enum _CV4001_MODE_E { + CV4001_MODE_2560X1440P25 = 0, + CV4001_MODE_LINEAR_NUM, + CV4001_MODE_2560X1440P15_WDR = CV4001_MODE_LINEAR_NUM, + CV4001_MODE_NUM +} CV4001_MODE_E; + +typedef struct _CV4001_STATE_S { + CVI_U32 u32Sexp_MAX; +} CV4001_STATE_S; + +typedef struct _CV4001_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]; +} CV4001_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastCV4001[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunCV4001_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeCV4001_MirrorFip[VI_MAX_PIPE_NUM]; +extern CVI_U8 cv4001_i2c_addr; +extern const CVI_U32 cv4001_addr_byte; +extern const CVI_U32 cv4001_data_byte; +extern void cv4001_init(VI_PIPE ViPipe); +extern void cv4001_exit(VI_PIPE ViPipe); +extern void cv4001_standby(VI_PIPE ViPipe); +extern void cv4001_restart(VI_PIPE ViPipe); +extern int cv4001_write_register(VI_PIPE ViPipe, int addr, int data); +extern int cv4001_read_register(VI_PIPE ViPipe, int addr); +extern int cv4001_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __CV4001_CMOS_EX_H_ */ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/cvsens_cv4001/cv4001_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/cvsens_cv4001/cv4001_cmos_param.h new file mode 100644 index 00000000..74855f38 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/cvsens_cv4001/cv4001_cmos_param.h @@ -0,0 +1,232 @@ +#ifndef __CV4001_CMOS_PARAM_H_ +#define __CV4001_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 "cv4001_cmos_ex.h" + +static const CV4001_MODE_S g_astCV4001_mode[CV4001_MODE_NUM] = { + [CV4001_MODE_2560X1440P25] = { + .name = "2560X1440P25", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2568, + .u32Height = 1448, + }, + .stWndRect = { + .s32X = 4, + .s32Y = 4, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2568, + .u32Height = 1448, + }, + }, + .f32MaxFps = 25, + .f32MinFps = 0.072, /* 1500 * 25 / (0x0FFFFF / 2) */ + .u32HtsDef = 1480, //hts_reg * 2 + .u32VtsDef = 1500, //vts_reg / 2 + .stExp[0] = { + .u16Min = 4, + .u16Max = 1500-2, + .u16Def = 4, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 16384, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16384, + .u32Def = 1024, + .u32Step = 64, + }, + }, + [CV4001_MODE_2560X1440P15_WDR] = { + .name = "2560X1440P15_WDR", + .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 = 15, + .f32MinFps = 0.084, /* 1474 * 15 / (0x0FFFFF / 4) */ + .u32HtsDef = 5088, //hts_reg * 4 + .u32VtsDef = 1474, //vts_reg / 4 + .stExp[0] = { + .u16Min = 4, + .u16Max = 1474-1, + .u16Def = 4, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 4, + .u16Max = 98, + .u16Def = 4, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 16384, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 16384, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16384, + .u32Def = 1024, + .u32Step = 64, + }, + .stDgain[1] = { + .u32Min = 1024, + .u32Max = 16384, + .u32Def = 1024, + .u32Step = 64, + }, + } +}; + + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {196, 196, 196, 196, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1075, 1075, 1075, 1075 +#endif + }, + .stAuto = { + {196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196 }, + {196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196 }, + {196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196 }, + {196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 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 + {1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, + 1075, 1075}, + {1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, + 1075, 1075}, + {1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, + 1075, 1075}, + {1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, + 1075, 1075}, +#endif + }, + }, +}; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio_wdr = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {196, 196, 196, 196, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1075, 1075, 1075, 1075 +#endif + }, + .stAuto = { + {196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196 }, + {196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196 }, + {196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196 }, + {196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 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 + {1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, + 1075, 1075}, + {1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, + 1075, 1075}, + {1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, + 1075, 1075}, + {1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, + 1075, 1075}, +#endif + }, + }, +}; + +struct combo_dev_attr_s cv4001_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_12BIT, + .lane_id = {1, 2, 0, -1, -1}, + .pn_swap = {1, 1, 1, 0, 0}, + .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 /* __CV4001_CMOS_PARAM_H_ */ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/cvsens_cv4001/cv4001_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/cvsens_cv4001/cv4001_sensor_ctl.c new file mode 100644 index 00000000..c6ddd0d7 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/cvsens_cv4001/cv4001_sensor_ctl.c @@ -0,0 +1,405 @@ +#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 "cv4001_cmos_ex.h" + +#define CV4001_CHIP_ID_ADDR_H 0x3003 +#define CV4001_CHIP_ID_ADDR_L 0x3002 +#define CV4001_CHIP_ID 0x4001 + +static void cv4001_linear_1440p25_init(VI_PIPE ViPipe); +static void cv4001_wdr_1440p15_2to1_init(VI_PIPE ViPipe); + +CVI_U8 cv4001_i2c_addr = 0x35; +const CVI_U32 cv4001_addr_byte = 2; +const CVI_U32 cv4001_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int cv4001_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunCV4001_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, cv4001_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 cv4001_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 cv4001_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 (cv4001_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, cv4001_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, cv4001_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (cv4001_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 cv4001_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 (cv4001_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + if (cv4001_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, cv4001_addr_byte + cv4001_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + ret = read(g_fd[ViPipe], buf, cv4001_addr_byte + cv4001_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 cv4001_standby(VI_PIPE ViPipe) +{ + cv4001_write_register(ViPipe, 0x3000, 0x1); + + printf("%s\n", __func__); +} + +void cv4001_restart(VI_PIPE ViPipe) +{ + cv4001_write_register(ViPipe, 0x3000, 0x01); + delay_ms(20); + cv4001_write_register(ViPipe, 0x3000, 0x00); + + printf("%s\n", __func__); +} + +void cv4001_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastCV4001[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + cv4001_write_register(ViPipe, + g_pastCV4001[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastCV4001[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +int cv4001_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (cv4001_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = cv4001_read_register(ViPipe, CV4001_CHIP_ID_ADDR_H); + nVal2 = cv4001_read_register(ViPipe, CV4001_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)) != CV4001_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void cv4001_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastCV4001[ViPipe]->enWDRMode; + u8ImgMode = g_pastCV4001[ViPipe]->u8ImgMode; + + cv4001_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == CV4001_MODE_2560X1440P15_WDR) { + cv4001_wdr_1440p15_2to1_init(ViPipe); + } + } else { + if (u8ImgMode == CV4001_MODE_2560X1440P25) { + cv4001_linear_1440p25_init(ViPipe); + } + } + + g_pastCV4001[ViPipe]->bInit = CVI_TRUE; +} + +void cv4001_exit(VI_PIPE ViPipe) +{ + cv4001_i2c_exit(ViPipe); +} + +static void cv4001_linear_1440p25_init(VI_PIPE ViPipe) +{ + delay_ms(10); + + //25fps 2lane + cv4001_write_register(ViPipe, 0x3028, 0xB8); + cv4001_write_register(ViPipe, 0x3029, 0x0B); + cv4001_write_register(ViPipe, 0x302C, 0xE4); + cv4001_write_register(ViPipe, 0x302D, 0x02); + cv4001_write_register(ViPipe, 0x3048, 0x40); + cv4001_write_register(ViPipe, 0x3049, 0x00); + cv4001_write_register(ViPipe, 0x304A, 0x08); + cv4001_write_register(ViPipe, 0x304B, 0x0A); + cv4001_write_register(ViPipe, 0x3054, 0x28); + cv4001_write_register(ViPipe, 0x3055, 0x00); + cv4001_write_register(ViPipe, 0x3056, 0xA8); + cv4001_write_register(ViPipe, 0x3057, 0x05); + cv4001_write_register(ViPipe, 0x3020, 0x04); + cv4001_write_register(ViPipe, 0x3908, 0x4A); + cv4001_write_register(ViPipe, 0x3306, 0x03); + cv4001_write_register(ViPipe, 0x343E, 0x00); + cv4001_write_register(ViPipe, 0x3401, 0x01); + cv4001_write_register(ViPipe, 0x3035, 0x01); + cv4001_write_register(ViPipe, 0x3036, 0x01); + cv4001_write_register(ViPipe, 0x343C, 0x01); + cv4001_write_register(ViPipe, 0x362A, 0x00); + cv4001_write_register(ViPipe, 0x3625, 0x01); + cv4001_write_register(ViPipe, 0x35A4, 0x09); + cv4001_write_register(ViPipe, 0x35A8, 0x09); + cv4001_write_register(ViPipe, 0x35AE, 0x07); + cv4001_write_register(ViPipe, 0x35AF, 0x07); + cv4001_write_register(ViPipe, 0x34A2, 0x2C); + cv4001_write_register(ViPipe, 0x3418, 0x9F); + cv4001_write_register(ViPipe, 0x341A, 0x57); + cv4001_write_register(ViPipe, 0x341C, 0x57); + cv4001_write_register(ViPipe, 0x341E, 0x6F); + cv4001_write_register(ViPipe, 0x341F, 0x01); + cv4001_write_register(ViPipe, 0x3420, 0x57); + cv4001_write_register(ViPipe, 0x3422, 0x9F); + cv4001_write_register(ViPipe, 0x3424, 0x57); + cv4001_write_register(ViPipe, 0x3426, 0x8F); + cv4001_write_register(ViPipe, 0x3428, 0x47); + cv4001_write_register(ViPipe, 0x3348, 0x00); + cv4001_write_register(ViPipe, 0x3000, 0x00); + cv4001_write_register(ViPipe, 0x3576, 0x06); + cv4001_write_register(ViPipe, 0x350F, 0x18); + cv4001_write_register(ViPipe, 0x3513, 0x07); + cv4001_write_register(ViPipe, 0x3517, 0x07); + cv4001_write_register(ViPipe, 0x351A, 0x05); + cv4001_write_register(ViPipe, 0x351E, 0x0B); + cv4001_write_register(ViPipe, 0x357A, 0x0B); + cv4001_write_register(ViPipe, 0x3348, 0x00); + cv4001_write_register(ViPipe, 0x316C, 0x64); + cv4001_write_register(ViPipe, 0x3258, 0x02); + cv4001_write_register(ViPipe, 0x3162, 0x01); + cv4001_write_register(ViPipe, 0x3347, 0x01); + cv4001_write_register(ViPipe, 0x3804, 0x0F); + cv4001_write_register(ViPipe, 0x3871, 0x00); + cv4001_write_register(ViPipe, 0x3244, 0x08); + cv4001_write_register(ViPipe, 0x3270, 0x60); + cv4001_write_register(ViPipe, 0x3271, 0x00); + cv4001_write_register(ViPipe, 0x3272, 0x00); + cv4001_write_register(ViPipe, 0x31AC, 0xC8); + cv4001_write_register(ViPipe, 0x3890, 0x00); + cv4001_write_register(ViPipe, 0x3894, 0x05); + cv4001_write_register(ViPipe, 0x3690, 0x00); + cv4001_write_register(ViPipe, 0x3898, 0x20); + cv4001_write_register(ViPipe, 0x3899, 0x20); + cv4001_write_register(ViPipe, 0x3583, 0x2f); + cv4001_write_register(ViPipe, 0x3b75, 0x00); + cv4001_write_register(ViPipe, 0x3b5E, 0x01); + cv4001_write_register(ViPipe, 0x3a10, 0x06); + cv4001_write_register(ViPipe, 0x3a11, 0x06); + cv4001_write_register(ViPipe, 0x316C, 0x64); + cv4001_write_register(ViPipe, 0x3000, 0x00); + + + cv4001_default_reg_init(ViPipe); + delay_ms(100); + + printf("ViPipe:%d,===CV4001 1440P 25fps 12bit LINEAR Init OK!===\n", ViPipe); +} + +static void cv4001_wdr_1440p15_2to1_init(VI_PIPE ViPipe) +{ + cv4001_write_register(ViPipe, 0x3028, 0x08); + cv4001_write_register(ViPipe, 0x3029, 0x17); + cv4001_write_register(ViPipe, 0x302C, 0xF8); + cv4001_write_register(ViPipe, 0x302D, 0x04); + cv4001_write_register(ViPipe, 0x3908, 0x4B); + cv4001_write_register(ViPipe, 0x3304, 0x01); + cv4001_write_register(ViPipe, 0x3305, 0x02); + cv4001_write_register(ViPipe, 0x3306, 0x01); + cv4001_write_register(ViPipe, 0x343E, 0x00); + cv4001_write_register(ViPipe, 0x3401, 0x03); + cv4001_write_register(ViPipe, 0x3035, 0x01); + cv4001_write_register(ViPipe, 0x3036, 0x01); + cv4001_write_register(ViPipe, 0x3020, 0x04); + cv4001_write_register(ViPipe, 0x3048, 0x44); + cv4001_write_register(ViPipe, 0x3049, 0x00); + cv4001_write_register(ViPipe, 0x304A, 0x00); + cv4001_write_register(ViPipe, 0x304B, 0x0A); + cv4001_write_register(ViPipe, 0x3054, 0x2C); + cv4001_write_register(ViPipe, 0x3056, 0xA8); + cv4001_write_register(ViPipe, 0x3057, 0x05); + cv4001_write_register(ViPipe, 0x3030, 0x05); + cv4001_write_register(ViPipe, 0x3060, 0x2C); + cv4001_write_register(ViPipe, 0x3064, 0x12); + cv4001_write_register(ViPipe, 0x3070, 0x1A);//62 + cv4001_write_register(ViPipe, 0x3071, 0x00); + cv4001_write_register(ViPipe, 0x343C, 0x01); + cv4001_write_register(ViPipe, 0x3930, 0x00); + cv4001_write_register(ViPipe, 0x3040, 0x01); + cv4001_write_register(ViPipe, 0x3044, 0x04); + cv4001_write_register(ViPipe, 0x3046, 0xA0); + cv4001_write_register(ViPipe, 0x3047, 0x05); + cv4001_write_register(ViPipe, 0x362A, 0x00); + cv4001_write_register(ViPipe, 0x3625, 0x01); + cv4001_write_register(ViPipe, 0x35A4, 0x09); + cv4001_write_register(ViPipe, 0x35A8, 0x09); + cv4001_write_register(ViPipe, 0x35AE, 0x07); + cv4001_write_register(ViPipe, 0x35AF, 0x07); + cv4001_write_register(ViPipe, 0x34A2, 0x2C); + cv4001_write_register(ViPipe, 0x3416, 0x0F); + cv4001_write_register(ViPipe, 0x3418, 0x9F); + cv4001_write_register(ViPipe, 0x341A, 0x57); + cv4001_write_register(ViPipe, 0x341C, 0x57); + cv4001_write_register(ViPipe, 0x341E, 0x6F); + cv4001_write_register(ViPipe, 0x341F, 0x01); + cv4001_write_register(ViPipe, 0x3420, 0x57); + cv4001_write_register(ViPipe, 0x3422, 0x9F); + cv4001_write_register(ViPipe, 0x3424, 0x57); + cv4001_write_register(ViPipe, 0x3426, 0x8F); + cv4001_write_register(ViPipe, 0x3428, 0x47); + cv4001_write_register(ViPipe, 0x3348, 0x00); + cv4001_write_register(ViPipe, 0x3000, 0x00); + cv4001_write_register(ViPipe, 0x3220, 0x03); + cv4001_write_register(ViPipe, 0x3347, 0x01); + cv4001_write_register(ViPipe, 0x3348, 0x00); + cv4001_write_register(ViPipe, 0x3804, 0x0F); + cv4001_write_register(ViPipe, 0x3576, 0x06); + cv4001_write_register(ViPipe, 0x350F, 0x18); + cv4001_write_register(ViPipe, 0x3513, 0x07); + cv4001_write_register(ViPipe, 0x3517, 0x07); + cv4001_write_register(ViPipe, 0x351A, 0x05); + cv4001_write_register(ViPipe, 0x351E, 0x0B); + cv4001_write_register(ViPipe, 0x357A, 0x0B); + cv4001_write_register(ViPipe, 0x3244, 0x08); + cv4001_write_register(ViPipe, 0x3270, 0x60); + cv4001_write_register(ViPipe, 0x3271, 0x00); + cv4001_write_register(ViPipe, 0x3272, 0x00); + cv4001_write_register(ViPipe, 0x3890, 0x01); + cv4001_write_register(ViPipe, 0x3894, 0x05); + cv4001_write_register(ViPipe, 0x3690, 0x00); + cv4001_write_register(ViPipe, 0x3898, 0x20); + cv4001_write_register(ViPipe, 0x3899, 0x20); + cv4001_write_register(ViPipe, 0x389a, 0x20); + cv4001_write_register(ViPipe, 0x389b, 0x20); + cv4001_write_register(ViPipe, 0x389c, 0x20); + cv4001_write_register(ViPipe, 0x389d, 0x15); + cv4001_write_register(ViPipe, 0x389e, 0x05); + cv4001_write_register(ViPipe, 0x3583, 0x2f); + cv4001_write_register(ViPipe, 0x3b75, 0x00); + cv4001_write_register(ViPipe, 0x3b5E, 0x01); + cv4001_write_register(ViPipe, 0x3a10, 0x06); + cv4001_write_register(ViPipe, 0x3a11, 0x06); + cv4001_write_register(ViPipe, 0x316C, 0x64); + cv4001_write_register(ViPipe, 0x3162, 0x01); + cv4001_write_register(ViPipe, 0x3180, 0x00); + cv4001_write_register(ViPipe, 0x3178, 0x40); + cv4001_write_register(ViPipe, 0x3179, 0x00); + + cv4001_default_reg_init(ViPipe); + delay_ms(100); + + printf("ViPipe:%d,===CV4001 1440P 15fps 12bit WDR2TO1 Init OK!===\n", ViPipe); +} + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc02m1/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc02m1/Makefile new file mode 100644 index 00000000..33f4be44 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc02m1/gc02m1_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc02m1/gc02m1_cmos.c new file mode 100644 index 00000000..c12c8703 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc02m1/gc02m1_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc02m1/gc02m1_cmos_ex.h new file mode 100644 index 00000000..62ca1b90 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc02m1/gc02m1_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc02m1/gc02m1_cmos_param.h new file mode 100644 index 00000000..24c74f4d --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc02m1/gc02m1_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc02m1/gc02m1_sensor_ctl.c new file mode 100644 index 00000000..2b41380f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0312/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0312/Makefile new file mode 100644 index 00000000..4a0e22f5 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0312/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_gc0312.a +TARGET_SO = $(MW_LIB)/libsns_gc0312.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0312/gc0312_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0312/gc0312_cmos.c new file mode 100644 index 00000000..0f5e654f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0312/gc0312_cmos.c @@ -0,0 +1,303 @@ +#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 "gc0312_cmos_ex.h" +#include "gc0312_cmos_param.h" + +#define GC0312_ID 0xb310 +#define GC0312_I2C_ADDR_1 0x21 +#define GC0312_I2C_ADDR_IS_VALID(addr) ((addr) == GC0312_I2C_ADDR_1) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc0312[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC0312_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc0312[dev]) +#define GC0312_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc0312[dev] = pstCtx) +#define GC0312_SENSOR_RESET_CTX(dev) (g_pastGc0312[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc0312_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +#define GC0312_RES_IS_480P(w, h) ((w) == 640 && (h) == 480) + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC0312_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC0312_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astGc0312_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); + GC0312_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); + GC0312_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 20) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC0312_RES_IS_480P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC0312_MODE_640X480P20; + 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; + + GC0312_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC0312_MODE_640X480P20; + 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; + + GC0312_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc0312_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astGc0312_mode.stImg.stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astGc0312_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 = &gc0312_rx_attr; + + 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; + + 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 = gc0312_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc0312_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 (GC0312_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc0312_i2c_addr = s32I2cAddr; +} + +static CVI_S32 gc0312_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc0312_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC0312_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)); + + GC0312_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC0312_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC0312_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 = GC0312_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, GC0312_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 gc0312_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc0312_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = CVI_NULL, + .pfnRestart = CVI_NULL, + .pfnWriteReg = gc0312_write_register, + .pfnReadReg = gc0312_read_register, + .pfnSetBusInfo = gc0312_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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0312/gc0312_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0312/gc0312_cmos_ex.h new file mode 100644 index 00000000..d06a6598 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0312/gc0312_cmos_ex.h @@ -0,0 +1,64 @@ +#ifndef __GC0312_CMOS_EX_H_ +#define __GC0312_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 _GC0312_MODE_E { + GC0312_MODE_640X480P20 = 0, + GC0312_MODE_NUM +} GC0312_SLAVE_MODE_E; + +typedef struct _GC0312_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]; +} GC0312_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc0312[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc0312_BusInfo[]; +extern CVI_U8 gc0312_i2c_addr; +extern const CVI_U32 gc0312_addr_byte; +extern const CVI_U32 gc0312_data_byte; +extern void gc0312_init(VI_PIPE ViPipe); +extern void gc0312_exit(VI_PIPE ViPipe); +extern void gc0312_standby(VI_PIPE ViPipe); +extern void gc0312_restart(VI_PIPE ViPipe); +extern int gc0312_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc0312_read_register(VI_PIPE ViPipe, int addr); +extern void gc0312_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int gc0312_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC0312_CMOS_EX_H_ */ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0312/gc0312_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0312/gc0312_cmos_param.h new file mode 100644 index 00000000..cfc16cc3 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0312/gc0312_cmos_param.h @@ -0,0 +1,71 @@ +#ifndef __GC0312_CMOS_PARAM_H_ +#define __GC0312_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 "gc0312_cmos_ex.h" + +static const GC0312_MODE_S g_astGc0312_mode = { + .name = "640X480P20", + .stImg = { + .stSnsSize = { + .u32Width = 640, + .u32Height = 480, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 640, + .u32Height = 480, + }, + .stMaxSize = { + .u32Width = 640, + .u32Height = 480, + }, + }, +}; + +struct combo_dev_attr_s gc0312_rx_attr = { + .input_mode = INPUT_MODE_BT601, + .mac_clk = RX_MAC_CLK_200M, + .ttl_attr = { + .vi = TTL_VI_SRC_VI0, + .ttl_fmt = TTL_VSDE_11B, + .raw_data_type = RAW_DATA_8BIT, + .func = { + 11, -1, -1, 12, + 1, 3, 4, 2, + 0, 5, 6, 7, + -1, -1, -1, -1, + -1, -1, -1, -1, + }, + }, + .mclk = { + .cam = 1, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC0312_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0312/gc0312_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0312/gc0312_sensor_ctl.c new file mode 100644 index 00000000..72405a1e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0312/gc0312_sensor_ctl.c @@ -0,0 +1,555 @@ +#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 "gc0312_cmos_ex.h" + +static void gc0312_linear_480p20_init(VI_PIPE ViPipe); + +CVI_U8 gc0312_i2c_addr = 0x21; +const CVI_U32 gc0312_addr_byte = 1; +const CVI_U32 gc0312_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc0312_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc0312_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, gc0312_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 gc0312_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 gc0312_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 (gc0312_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc0312_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, gc0312_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc0312_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 gc0312_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 (gc0312_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (gc0312_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc0312_addr_byte + gc0312_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 GC0312_CHIP_ID 0xb310 +#define GC0312_CHIP_ID_ADDR_H 0xf0 +#define GC0312_CHIP_ID_ADDR_L 0xf1 + +int gc0312_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc0312_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc0312_read_register(ViPipe, GC0312_CHIP_ID_ADDR_H); + nVal2 = gc0312_read_register(ViPipe, GC0312_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)) != GC0312_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + printf("%d\n", ViPipe); + return CVI_SUCCESS; +} + +void gc0312_init(VI_PIPE ViPipe) +{ + gc0312_i2c_init(ViPipe); + + gc0312_linear_480p20_init(ViPipe); + + g_pastGc0312[ViPipe]->bInit = CVI_TRUE; +} + +void gc0312_exit(VI_PIPE ViPipe) +{ + gc0312_i2c_exit(ViPipe); +} + +static void gc0312_linear_480p20_init(VI_PIPE ViPipe) +{ + gc0312_write_register(ViPipe, 0xfe, 0xf0); + gc0312_write_register(ViPipe, 0xfe, 0xf0); + gc0312_write_register(ViPipe, 0xfe, 0x00); + gc0312_write_register(ViPipe, 0xfc, 0x0e); + gc0312_write_register(ViPipe, 0xfc, 0x0e); + gc0312_write_register(ViPipe, 0xf2, 0x07); + gc0312_write_register(ViPipe, 0xf3, 0x00);// output_disable + gc0312_write_register(ViPipe, 0xf7, 0x1b); + gc0312_write_register(ViPipe, 0xf8, 0x04); + gc0312_write_register(ViPipe, 0xf9, 0x0e); + gc0312_write_register(ViPipe, 0xfa, 0x11); + + ///////////////////////////////////////////////// + ///////////////// CISCTL reg ///////////////// + ///////////////////////////////////////////////// + gc0312_write_register(ViPipe, 0x00, 0x2f); + gc0312_write_register(ViPipe, 0x01, 0x0f); + gc0312_write_register(ViPipe, 0x02, 0x04); + gc0312_write_register(ViPipe, 0x03, 0x03); + gc0312_write_register(ViPipe, 0x04, 0x50); + gc0312_write_register(ViPipe, 0x09, 0x00); + gc0312_write_register(ViPipe, 0x0a, 0x00); + gc0312_write_register(ViPipe, 0x0b, 0x00); + gc0312_write_register(ViPipe, 0x0c, 0x04); + gc0312_write_register(ViPipe, 0x0d, 0x01); + gc0312_write_register(ViPipe, 0x0e, 0xe8); + gc0312_write_register(ViPipe, 0x0f, 0x02); + gc0312_write_register(ViPipe, 0x10, 0x88); + gc0312_write_register(ViPipe, 0x16, 0x00); + gc0312_write_register(ViPipe, 0x17, 0x14); + gc0312_write_register(ViPipe, 0x18, 0x1a); + gc0312_write_register(ViPipe, 0x19, 0x14); + gc0312_write_register(ViPipe, 0x1b, 0x48); + gc0312_write_register(ViPipe, 0x1c, 0x6c);//1c travis 20140929 + gc0312_write_register(ViPipe, 0x1e, 0x6b); + gc0312_write_register(ViPipe, 0x1f, 0x28); + gc0312_write_register(ViPipe, 0x20, 0x8b);//89 travis 20140801 + gc0312_write_register(ViPipe, 0x21, 0x49); + gc0312_write_register(ViPipe, 0x22, 0xd0);//b0 travis 20140929 + gc0312_write_register(ViPipe, 0x23, 0x04); + gc0312_write_register(ViPipe, 0x24, 0x16); + gc0312_write_register(ViPipe, 0x34, 0x20); + + ///////////////////////////////////////////////// + //////////////////// BLK //////////////////// + ///////////////////////////////////////////////// + gc0312_write_register(ViPipe, 0x26, 0x23); + gc0312_write_register(ViPipe, 0x28, 0xff); + gc0312_write_register(ViPipe, 0x29, 0x00); + gc0312_write_register(ViPipe, 0x32, 0x04);//00 travis 20140929 + gc0312_write_register(ViPipe, 0x33, 0x10); + gc0312_write_register(ViPipe, 0x37, 0x20); + gc0312_write_register(ViPipe, 0x38, 0x10); + gc0312_write_register(ViPipe, 0x47, 0x80); + gc0312_write_register(ViPipe, 0x4e, 0x66); + gc0312_write_register(ViPipe, 0xa8, 0x02); + gc0312_write_register(ViPipe, 0xa9, 0x80); + + ///////////////////////////////////////////////// + ////////////////// ISP reg /////////////////// + ///////////////////////////////////////////////// + gc0312_write_register(ViPipe, 0x40, 0xff); + gc0312_write_register(ViPipe, 0x41, 0x21); + gc0312_write_register(ViPipe, 0x42, 0xcf); + gc0312_write_register(ViPipe, 0x44, 0x02); + gc0312_write_register(ViPipe, 0x45, 0xa8); + gc0312_write_register(ViPipe, 0x46, 0x02); + gc0312_write_register(ViPipe, 0x4a, 0x11); + gc0312_write_register(ViPipe, 0x4b, 0x01); + gc0312_write_register(ViPipe, 0x4c, 0x20); + gc0312_write_register(ViPipe, 0x4d, 0x05); + gc0312_write_register(ViPipe, 0x4f, 0x01); + gc0312_write_register(ViPipe, 0x50, 0x01); + gc0312_write_register(ViPipe, 0x55, 0x01); + gc0312_write_register(ViPipe, 0x56, 0xe0); + gc0312_write_register(ViPipe, 0x57, 0x02); + gc0312_write_register(ViPipe, 0x58, 0x80); + + ///////////////////////////////////////////////// + /////////////////// GAIN //////////////////// + ///////////////////////////////////////////////// + gc0312_write_register(ViPipe, 0x70, 0x70); + gc0312_write_register(ViPipe, 0x5a, 0x84); + gc0312_write_register(ViPipe, 0x5b, 0xc9); + gc0312_write_register(ViPipe, 0x5c, 0xed); + gc0312_write_register(ViPipe, 0x77, 0x74); + gc0312_write_register(ViPipe, 0x78, 0x40); + gc0312_write_register(ViPipe, 0x79, 0x5f); + + ///////////////////////////////////////////////// + /////////////////// DNDD ///////////////////// + ///////////////////////////////////////////////// + gc0312_write_register(ViPipe, 0x82, 0x14); + gc0312_write_register(ViPipe, 0x83, 0x0b); + gc0312_write_register(ViPipe, 0x89, 0xf0); + + ///////////////////////////////////////////////// + ////////////////// EEINTP //////////////////// + ///////////////////////////////////////////////// + gc0312_write_register(ViPipe, 0x8f, 0xaa); + gc0312_write_register(ViPipe, 0x90, 0x8c); + gc0312_write_register(ViPipe, 0x91, 0x90); + gc0312_write_register(ViPipe, 0x92, 0x03); + gc0312_write_register(ViPipe, 0x93, 0x03); + gc0312_write_register(ViPipe, 0x94, 0x05); + gc0312_write_register(ViPipe, 0x95, 0x65); + gc0312_write_register(ViPipe, 0x96, 0xf0); + + ///////////////////////////////////////////////// + ///////////////////// ASDE //////////////////// + ///////////////////////////////////////////////// + gc0312_write_register(ViPipe, 0xfe, 0x00); + + gc0312_write_register(ViPipe, 0x9a, 0x20); + gc0312_write_register(ViPipe, 0x9b, 0x80); + gc0312_write_register(ViPipe, 0x9c, 0x40); + gc0312_write_register(ViPipe, 0x9d, 0x80); + + gc0312_write_register(ViPipe, 0xa1, 0x30); + gc0312_write_register(ViPipe, 0xa2, 0x32); + gc0312_write_register(ViPipe, 0xa4, 0x80);//30 travis 20140929 + gc0312_write_register(ViPipe, 0xa5, 0x28);//30 travis 20140929 + gc0312_write_register(ViPipe, 0xaa, 0x30);//10 travis 20140929 + gc0312_write_register(ViPipe, 0xac, 0x22); + + ///////////////////////////////////////////////// + /////////////////// GAMMA /////////////////// + ///////////////////////////////////////////////// + gc0312_write_register(ViPipe, 0xfe, 0x00);//default + gc0312_write_register(ViPipe, 0xbf, 0x08); + gc0312_write_register(ViPipe, 0xc0, 0x16); + gc0312_write_register(ViPipe, 0xc1, 0x28); + gc0312_write_register(ViPipe, 0xc2, 0x41); + gc0312_write_register(ViPipe, 0xc3, 0x5a); + gc0312_write_register(ViPipe, 0xc4, 0x6c); + gc0312_write_register(ViPipe, 0xc5, 0x7a); + gc0312_write_register(ViPipe, 0xc6, 0x96); + gc0312_write_register(ViPipe, 0xc7, 0xac); + gc0312_write_register(ViPipe, 0xc8, 0xbc); + gc0312_write_register(ViPipe, 0xc9, 0xc9); + gc0312_write_register(ViPipe, 0xca, 0xd3); + gc0312_write_register(ViPipe, 0xcb, 0xdd); + gc0312_write_register(ViPipe, 0xcc, 0xe5); + gc0312_write_register(ViPipe, 0xcd, 0xf1); + gc0312_write_register(ViPipe, 0xce, 0xfa); + gc0312_write_register(ViPipe, 0xcf, 0xff); + ///////////////////////////////////////////////// + /////////////////// YCP ////////////////////// + ///////////////////////////////////////////////// + gc0312_write_register(ViPipe, 0xd0, 0x40); + gc0312_write_register(ViPipe, 0xd1, 0x34); + gc0312_write_register(ViPipe, 0xd2, 0x34); + gc0312_write_register(ViPipe, 0xd3, 0x40); + gc0312_write_register(ViPipe, 0xd6, 0xf2); + gc0312_write_register(ViPipe, 0xd7, 0x1b); + gc0312_write_register(ViPipe, 0xd8, 0x18); + gc0312_write_register(ViPipe, 0xdd, 0x03); + + ///////////////////////////////////////////////// + //////////////////// AEC //////////////////// + ///////////////////////////////////////////////// + gc0312_write_register(ViPipe, 0xfe, 0x01); + gc0312_write_register(ViPipe, 0x05, 0x30); + gc0312_write_register(ViPipe, 0x06, 0x75); + gc0312_write_register(ViPipe, 0x07, 0x40); + gc0312_write_register(ViPipe, 0x08, 0xb0); + gc0312_write_register(ViPipe, 0x0a, 0xc5); + gc0312_write_register(ViPipe, 0x0b, 0x11); + gc0312_write_register(ViPipe, 0x0c, 0x00); + gc0312_write_register(ViPipe, 0x12, 0x52); + gc0312_write_register(ViPipe, 0x13, 0x38); + gc0312_write_register(ViPipe, 0x18, 0x95); + gc0312_write_register(ViPipe, 0x19, 0x96); + gc0312_write_register(ViPipe, 0x1f, 0x20); + gc0312_write_register(ViPipe, 0x20, 0xc0); + gc0312_write_register(ViPipe, 0x3e, 0x40); + gc0312_write_register(ViPipe, 0x3f, 0x57); + gc0312_write_register(ViPipe, 0x40, 0x7d); + gc0312_write_register(ViPipe, 0x03, 0x60); + gc0312_write_register(ViPipe, 0x44, 0x02); + + ///////////////////////////////////////////////// + //////////////////// AWB //////////////////// + ///////////////////////////////////////////////// + gc0312_write_register(ViPipe, 0xfe, 0x01); + gc0312_write_register(ViPipe, 0x1c, 0x91); + gc0312_write_register(ViPipe, 0x21, 0x15); + gc0312_write_register(ViPipe, 0x50, 0x80); + gc0312_write_register(ViPipe, 0x56, 0x04); + gc0312_write_register(ViPipe, 0x59, 0x08); + gc0312_write_register(ViPipe, 0x5b, 0x02); + gc0312_write_register(ViPipe, 0x61, 0x8d); + gc0312_write_register(ViPipe, 0x62, 0xa7); + gc0312_write_register(ViPipe, 0x63, 0xd0); + gc0312_write_register(ViPipe, 0x65, 0x06); + gc0312_write_register(ViPipe, 0x66, 0x06); + gc0312_write_register(ViPipe, 0x67, 0x84); + gc0312_write_register(ViPipe, 0x69, 0x08); + gc0312_write_register(ViPipe, 0x6a, 0x25); + gc0312_write_register(ViPipe, 0x6b, 0x01); + gc0312_write_register(ViPipe, 0x6c, 0x00); + gc0312_write_register(ViPipe, 0x6d, 0x02); + gc0312_write_register(ViPipe, 0x6e, 0xf0); + gc0312_write_register(ViPipe, 0x6f, 0x80); + gc0312_write_register(ViPipe, 0x76, 0x80); + gc0312_write_register(ViPipe, 0x78, 0xaf); + gc0312_write_register(ViPipe, 0x79, 0x75); + gc0312_write_register(ViPipe, 0x7a, 0x40); + gc0312_write_register(ViPipe, 0x7b, 0x50); + gc0312_write_register(ViPipe, 0x7c, 0x0c); + + + gc0312_write_register(ViPipe, 0x90, 0xc9);//stable AWB + gc0312_write_register(ViPipe, 0x91, 0xbe); + gc0312_write_register(ViPipe, 0x92, 0xe2); + gc0312_write_register(ViPipe, 0x93, 0xc9); + gc0312_write_register(ViPipe, 0x95, 0x1b); + gc0312_write_register(ViPipe, 0x96, 0xe2); + gc0312_write_register(ViPipe, 0x97, 0x49); + gc0312_write_register(ViPipe, 0x98, 0x1b); + gc0312_write_register(ViPipe, 0x9a, 0x49); + gc0312_write_register(ViPipe, 0x9b, 0x1b); + gc0312_write_register(ViPipe, 0x9c, 0xc3); + gc0312_write_register(ViPipe, 0x9d, 0x49); + gc0312_write_register(ViPipe, 0x9f, 0xc7); + gc0312_write_register(ViPipe, 0xa0, 0xc8); + gc0312_write_register(ViPipe, 0xa1, 0x00); + gc0312_write_register(ViPipe, 0xa2, 0x00); + gc0312_write_register(ViPipe, 0x86, 0x00); + gc0312_write_register(ViPipe, 0x87, 0x00); + gc0312_write_register(ViPipe, 0x88, 0x00); + gc0312_write_register(ViPipe, 0x89, 0x00); + gc0312_write_register(ViPipe, 0xa4, 0xb9); + gc0312_write_register(ViPipe, 0xa5, 0xa0); + gc0312_write_register(ViPipe, 0xa6, 0xba); + gc0312_write_register(ViPipe, 0xa7, 0x92); + gc0312_write_register(ViPipe, 0xa9, 0xba); + gc0312_write_register(ViPipe, 0xaa, 0x80); + gc0312_write_register(ViPipe, 0xab, 0x9d); + gc0312_write_register(ViPipe, 0xac, 0x7f); + gc0312_write_register(ViPipe, 0xae, 0xbb); + gc0312_write_register(ViPipe, 0xaf, 0x9d); + gc0312_write_register(ViPipe, 0xb0, 0xc8); + gc0312_write_register(ViPipe, 0xb1, 0x97); + gc0312_write_register(ViPipe, 0xb3, 0xb7); + gc0312_write_register(ViPipe, 0xb4, 0x7f); + gc0312_write_register(ViPipe, 0xb5, 0x00); + gc0312_write_register(ViPipe, 0xb6, 0x00); + gc0312_write_register(ViPipe, 0x8b, 0x00); + gc0312_write_register(ViPipe, 0x8c, 0x00); + gc0312_write_register(ViPipe, 0x8d, 0x00); + gc0312_write_register(ViPipe, 0x8e, 0x00); + gc0312_write_register(ViPipe, 0x94, 0x55); + gc0312_write_register(ViPipe, 0x99, 0xa6); + gc0312_write_register(ViPipe, 0x9e, 0xaa); + gc0312_write_register(ViPipe, 0xa3, 0x0a); + gc0312_write_register(ViPipe, 0x8a, 0x00); + gc0312_write_register(ViPipe, 0xa8, 0x55); + gc0312_write_register(ViPipe, 0xad, 0x55); + gc0312_write_register(ViPipe, 0xb2, 0x55); + gc0312_write_register(ViPipe, 0xb7, 0x05); + gc0312_write_register(ViPipe, 0x8f, 0x00); + gc0312_write_register(ViPipe, 0xb8, 0xcb); + gc0312_write_register(ViPipe, 0xb9, 0x9b); + ///////////////////////////////////////////////// + //////////////////// CC //////////////////// + ///////////////////////////////////////////////// + gc0312_write_register(ViPipe, 0xfe, 0x01); + + gc0312_write_register(ViPipe, 0xd0, 0x38);//skin red + gc0312_write_register(ViPipe, 0xd1, 0x00); + gc0312_write_register(ViPipe, 0xd2, 0x02); + gc0312_write_register(ViPipe, 0xd3, 0x04); + gc0312_write_register(ViPipe, 0xd4, 0x38); + gc0312_write_register(ViPipe, 0xd5, 0x12); + gc0312_write_register(ViPipe, 0xd6, 0x30); + gc0312_write_register(ViPipe, 0xd7, 0x00); + gc0312_write_register(ViPipe, 0xd8, 0x0a); + gc0312_write_register(ViPipe, 0xd9, 0x16); + gc0312_write_register(ViPipe, 0xda, 0x39); + gc0312_write_register(ViPipe, 0xdb, 0xf8); + + ///////////////////////////////////////////////// + //////////////////// LSC //////////////////// + ///////////////////////////////////////////////// + gc0312_write_register(ViPipe, 0xfe, 0x01); + gc0312_write_register(ViPipe, 0xc1, 0x3c); + gc0312_write_register(ViPipe, 0xc2, 0x50); + gc0312_write_register(ViPipe, 0xc3, 0x00); + gc0312_write_register(ViPipe, 0xc4, 0x40); + gc0312_write_register(ViPipe, 0xc5, 0x30); + gc0312_write_register(ViPipe, 0xc6, 0x30); + gc0312_write_register(ViPipe, 0xc7, 0x10); + gc0312_write_register(ViPipe, 0xc8, 0x00); + gc0312_write_register(ViPipe, 0xc9, 0x00); + gc0312_write_register(ViPipe, 0xdc, 0x20); + gc0312_write_register(ViPipe, 0xdd, 0x10); + gc0312_write_register(ViPipe, 0xdf, 0x00); + gc0312_write_register(ViPipe, 0xde, 0x00); + + ///////////////////////////////////////////////// + /////////////////// Histogram ///////////////// + ///////////////////////////////////////////////// + gc0312_write_register(ViPipe, 0x01, 0x10); + gc0312_write_register(ViPipe, 0x0b, 0x31); + gc0312_write_register(ViPipe, 0x0e, 0x50); + gc0312_write_register(ViPipe, 0x0f, 0x0f); + gc0312_write_register(ViPipe, 0x10, 0x6e); + gc0312_write_register(ViPipe, 0x12, 0xa0); + gc0312_write_register(ViPipe, 0x15, 0x60); + gc0312_write_register(ViPipe, 0x16, 0x60); + gc0312_write_register(ViPipe, 0x17, 0xe0); + + ///////////////////////////////////////////////// + ////////////// Measure Window /////////////// + ///////////////////////////////////////////////// + gc0312_write_register(ViPipe, 0xcc, 0x0c); + gc0312_write_register(ViPipe, 0xcd, 0x10); + gc0312_write_register(ViPipe, 0xce, 0xa0); + gc0312_write_register(ViPipe, 0xcf, 0xe6); + + ///////////////////////////////////////////////// + ///////////////// dark sun ////////////////// + ///////////////////////////////////////////////// + gc0312_write_register(ViPipe, 0x45, 0xf7); + gc0312_write_register(ViPipe, 0x46, 0xff); + gc0312_write_register(ViPipe, 0x47, 0x15); + gc0312_write_register(ViPipe, 0x48, 0x03); + gc0312_write_register(ViPipe, 0x4f, 0x60); + + //////////////////banding////////////////////// + gc0312_write_register(ViPipe, 0xfe, 0x00); + gc0312_write_register(ViPipe, 0x05, 0x02); + gc0312_write_register(ViPipe, 0x06, 0xd1); //HB + gc0312_write_register(ViPipe, 0x07, 0x00); + gc0312_write_register(ViPipe, 0x08, 0x22); //VB + + gc0312_write_register(ViPipe, 0xfe, 0x01); + gc0312_write_register(ViPipe, 0x25, 0x00); //anti-flicker step [11:8] + gc0312_write_register(ViPipe, 0x26, 0x6a); //anti-flicker step [7:0] + + gc0312_write_register(ViPipe, 0x27, 0x02); //exp level 0 20fps + gc0312_write_register(ViPipe, 0x28, 0x12); + gc0312_write_register(ViPipe, 0x29, 0x03); //exp level 1 12.50fps + gc0312_write_register(ViPipe, 0x2a, 0x50); + gc0312_write_register(ViPipe, 0x2b, 0x05); //7.14fps + gc0312_write_register(ViPipe, 0x2c, 0xcc); + gc0312_write_register(ViPipe, 0x2d, 0x07); //exp level 3 5.55fps + gc0312_write_register(ViPipe, 0x2e, 0x74); + gc0312_write_register(ViPipe, 0x3c, 0x20); + gc0312_write_register(ViPipe, 0xfe, 0x00); + + ///////////////////////////////////////////////// + ///////////////////// DVP //////////////////// + ///////////////////////////////////////////////// + gc0312_write_register(ViPipe, 0xfe, 0x03); + gc0312_write_register(ViPipe, 0x01, 0x00); + gc0312_write_register(ViPipe, 0x02, 0x00); + gc0312_write_register(ViPipe, 0x10, 0x00); + gc0312_write_register(ViPipe, 0x15, 0x00); + gc0312_write_register(ViPipe, 0xfe, 0x00); + ///////////////////OUTPUT////////////////////// + gc0312_write_register(ViPipe, 0xf3, 0xff);// output_enable + + + delay_ms(50); + + printf("ViPipe:%d,===GC0312 480P 20fps YUV Init OK!===\n", ViPipe); +} + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0329/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0329/Makefile new file mode 100644 index 00000000..5bbcfd07 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0329/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_gc0329.a +TARGET_SO = $(MW_LIB)/libsns_gc0329.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0329/gc0329_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0329/gc0329_cmos.c new file mode 100644 index 00000000..5b5a220d --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0329/gc0329_cmos.c @@ -0,0 +1,303 @@ +#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 "gc0329_cmos_ex.h" +#include "gc0329_cmos_param.h" + +#define GC0329_ID 0xc0 +#define GC0329_I2C_ADDR_1 0x31 +#define GC0329_I2C_ADDR_IS_VALID(addr) ((addr) == GC0329_I2C_ADDR_1) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc0329[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC0329_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc0329[dev]) +#define GC0329_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc0329[dev] = pstCtx) +#define GC0329_SENSOR_RESET_CTX(dev) (g_pastGc0329[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc0329_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +#define GC0329_RES_IS_480P(w, h) ((w) == 640 && (h) == 480) + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC0329_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC0329_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astGc0329_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); + GC0329_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); + GC0329_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 10) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC0329_RES_IS_480P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC0329_MODE_640X480P10; + 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; + + GC0329_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC0329_MODE_640X480P10; + 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; + + GC0329_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc0329_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astGc0329_mode.stImg.stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astGc0329_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 = &gc0329_rx_attr; + + 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; + + 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 = gc0329_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc0329_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 (GC0329_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc0329_i2c_addr = s32I2cAddr; +} + +static CVI_S32 gc0329_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc0329_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC0329_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)); + + GC0329_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC0329_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC0329_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 = GC0329_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, GC0329_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 gc0329_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc0329_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = CVI_NULL, + .pfnRestart = CVI_NULL, + .pfnWriteReg = gc0329_write_register, + .pfnReadReg = gc0329_read_register, + .pfnSetBusInfo = gc0329_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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0329/gc0329_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0329/gc0329_cmos_ex.h new file mode 100644 index 00000000..9ad3c8be --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0329/gc0329_cmos_ex.h @@ -0,0 +1,64 @@ +#ifndef __GC0329_CMOS_EX_H_ +#define __GC0329_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 _GC0329_MODE_E { + GC0329_MODE_640X480P10 = 0, + GC0329_MODE_NUM +} GC0329_SLAVE_MODE_E; + +typedef struct _GC0329_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]; +} GC0329_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc0329[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc0329_BusInfo[]; +extern CVI_U8 gc0329_i2c_addr; +extern const CVI_U32 gc0329_addr_byte; +extern const CVI_U32 gc0329_data_byte; +extern void gc0329_init(VI_PIPE ViPipe); +extern void gc0329_exit(VI_PIPE ViPipe); +extern void gc0329_standby(VI_PIPE ViPipe); +extern void gc0329_restart(VI_PIPE ViPipe); +extern int gc0329_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc0329_read_register(VI_PIPE ViPipe, int addr); +extern void gc0329_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int gc0329_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC0329_CMOS_EX_H_ */ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0329/gc0329_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0329/gc0329_cmos_param.h new file mode 100644 index 00000000..56a42de3 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0329/gc0329_cmos_param.h @@ -0,0 +1,71 @@ +#ifndef __GC0329_CMOS_PARAM_H_ +#define __GC0329_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 "gc0329_cmos_ex.h" + +static const GC0329_MODE_S g_astGc0329_mode = { + .name = "640X480P10", + .stImg = { + .stSnsSize = { + .u32Width = 640, + .u32Height = 480, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 640, + .u32Height = 480, + }, + .stMaxSize = { + .u32Width = 640, + .u32Height = 480, + }, + }, +}; + +struct combo_dev_attr_s gc0329_rx_attr = { + .input_mode = INPUT_MODE_BT601, + .mac_clk = RX_MAC_CLK_200M, + .ttl_attr = { + .vi = TTL_VI_SRC_VI0, + .ttl_fmt = TTL_VSDE_11B, + .raw_data_type = RAW_DATA_8BIT, + .func = { + 8, -1, -1, 12, + 0, 1, 2, 3, + 4, 13, 14, 11, + -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 /* __GC0329_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0329/gc0329_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0329/gc0329_sensor_ctl.c new file mode 100644 index 00000000..1bdd8753 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc0329/gc0329_sensor_ctl.c @@ -0,0 +1,464 @@ +#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 "gc0329_cmos_ex.h" + +static void gc0329_linear_480p10_init(VI_PIPE ViPipe); + +CVI_U8 gc0329_i2c_addr = 0x31;//0x78 +const CVI_U32 gc0329_addr_byte = 1; +const CVI_U32 gc0329_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc0329_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc0329_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, gc0329_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 gc0329_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 gc0329_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 (gc0329_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc0329_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, gc0329_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc0329_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 gc0329_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 (gc0329_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (gc0329_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc0329_addr_byte + gc0329_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 GC0329_CHIP_ID_ADDR 0x00 +#define GC0329_CHIP_ID 0xc0 + +int gc0329_probe(VI_PIPE ViPipe) +{ + int nVal; + + usleep(50); + if (gc0329_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + gc0329_write_register(ViPipe, 0xfc, 0x16); + nVal = gc0329_read_register(ViPipe, GC0329_CHIP_ID_ADDR); + if (nVal < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((nVal & 0xFF) != GC0329_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + printf("%d\n", ViPipe); + return CVI_SUCCESS; +} + +void gc0329_init(VI_PIPE ViPipe) +{ + gc0329_i2c_init(ViPipe); + + gc0329_linear_480p10_init(ViPipe); + + g_pastGc0329[ViPipe]->bInit = CVI_TRUE; +} + +void gc0329_exit(VI_PIPE ViPipe) +{ + gc0329_i2c_exit(ViPipe); +} + +static void gc0329_linear_480p10_init(VI_PIPE ViPipe) +{ + gc0329_write_register(ViPipe, 0xfe, 0x80); + gc0329_write_register(ViPipe, 0xfc, 0x16); + gc0329_write_register(ViPipe, 0xfc, 0x16); + gc0329_write_register(ViPipe, 0xfe, 0x00); + gc0329_write_register(ViPipe, 0x70, 0x48); + gc0329_write_register(ViPipe, 0x73, 0x90); + gc0329_write_register(ViPipe, 0x74, 0x80); + gc0329_write_register(ViPipe, 0x75, 0x80); + gc0329_write_register(ViPipe, 0x76, 0x94); + gc0329_write_register(ViPipe, 0x77, 0x62); + gc0329_write_register(ViPipe, 0x78, 0x47); + gc0329_write_register(ViPipe, 0x79, 0x40); + + gc0329_write_register(ViPipe, 0x03, 0x02); + gc0329_write_register(ViPipe, 0x04, 0x40); + + gc0329_write_register(ViPipe, 0xfc, 0x16); + gc0329_write_register(ViPipe, 0x09, 0x00); + gc0329_write_register(ViPipe, 0x0a, 0x02); + gc0329_write_register(ViPipe, 0x0b, 0x00); + gc0329_write_register(ViPipe, 0x0c, 0x02); + gc0329_write_register(ViPipe, 0x17, 0x14); + gc0329_write_register(ViPipe, 0x19, 0x05); + gc0329_write_register(ViPipe, 0x1b, 0x24); + gc0329_write_register(ViPipe, 0x1c, 0x04); + gc0329_write_register(ViPipe, 0x1e, 0x08); + gc0329_write_register(ViPipe, 0x1f, 0x08); + gc0329_write_register(ViPipe, 0x20, 0x01); + gc0329_write_register(ViPipe, 0x21, 0x48); + gc0329_write_register(ViPipe, 0x22, 0xba); + gc0329_write_register(ViPipe, 0x23, 0x22); + gc0329_write_register(ViPipe, 0x24, 0x16); + + gc0329_write_register(ViPipe, 0x26, 0xf7); + gc0329_write_register(ViPipe, 0x28, 0x7f); + gc0329_write_register(ViPipe, 0x29, 0x00); + gc0329_write_register(ViPipe, 0x32, 0x00); + gc0329_write_register(ViPipe, 0x33, 0x20); + gc0329_write_register(ViPipe, 0x34, 0x20); + gc0329_write_register(ViPipe, 0x35, 0x20); + gc0329_write_register(ViPipe, 0x36, 0x20); + + gc0329_write_register(ViPipe, 0x3b, 0x04); + gc0329_write_register(ViPipe, 0x3c, 0x04); + gc0329_write_register(ViPipe, 0x3d, 0x04); + gc0329_write_register(ViPipe, 0x3e, 0x04); + + gc0329_write_register(ViPipe, 0x40, 0xff); + gc0329_write_register(ViPipe, 0x41, 0x24); + gc0329_write_register(ViPipe, 0x42, 0xfa); + gc0329_write_register(ViPipe, 0x46, 0x02); + gc0329_write_register(ViPipe, 0x4b, 0xca); + gc0329_write_register(ViPipe, 0x4d, 0x01); + gc0329_write_register(ViPipe, 0x4f, 0x01); + gc0329_write_register(ViPipe, 0x70, 0x48); + + gc0329_write_register(ViPipe, 0x80, 0x07); + gc0329_write_register(ViPipe, 0x81, 0xc2); + gc0329_write_register(ViPipe, 0x82, 0x90); + gc0329_write_register(ViPipe, 0x83, 0x05); + gc0329_write_register(ViPipe, 0x87, 0x40); + + gc0329_write_register(ViPipe, 0x90, 0x8c); + gc0329_write_register(ViPipe, 0x92, 0x05); + gc0329_write_register(ViPipe, 0x94, 0x05); + gc0329_write_register(ViPipe, 0x95, 0x45); + gc0329_write_register(ViPipe, 0x96, 0x88); + + gc0329_write_register(ViPipe, 0xfe, 0x01); + gc0329_write_register(ViPipe, 0x18, 0x22); + gc0329_write_register(ViPipe, 0xfe, 0x00); + gc0329_write_register(ViPipe, 0x9c, 0x0a); + gc0329_write_register(ViPipe, 0xa0, 0xaf); + gc0329_write_register(ViPipe, 0xa2, 0xff); + gc0329_write_register(ViPipe, 0xa4, 0x30); + gc0329_write_register(ViPipe, 0xa5, 0x31); + gc0329_write_register(ViPipe, 0xa7, 0x35); + + gc0329_write_register(ViPipe, 0xfe, 0x00); + gc0329_write_register(ViPipe, 0xbf, 0x0b); + gc0329_write_register(ViPipe, 0xc0, 0x1d); + gc0329_write_register(ViPipe, 0xc1, 0x33); + gc0329_write_register(ViPipe, 0xc2, 0x49); + gc0329_write_register(ViPipe, 0xc3, 0x5d); + gc0329_write_register(ViPipe, 0xc4, 0x6e); + gc0329_write_register(ViPipe, 0xc5, 0x7c); + gc0329_write_register(ViPipe, 0xc6, 0x99); + gc0329_write_register(ViPipe, 0xc7, 0xaf); + gc0329_write_register(ViPipe, 0xc8, 0xc2); + gc0329_write_register(ViPipe, 0xc9, 0xd0); + gc0329_write_register(ViPipe, 0xca, 0xda); + gc0329_write_register(ViPipe, 0xcb, 0xe2); + gc0329_write_register(ViPipe, 0xcc, 0xe7); + gc0329_write_register(ViPipe, 0xcd, 0xf0); + gc0329_write_register(ViPipe, 0xce, 0xf7); + gc0329_write_register(ViPipe, 0xcf, 0xff); + + gc0329_write_register(ViPipe, 0xfe, 0x00); + gc0329_write_register(ViPipe, 0x63, 0x00); + gc0329_write_register(ViPipe, 0x64, 0x06); + gc0329_write_register(ViPipe, 0x65, 0x0d); + gc0329_write_register(ViPipe, 0x66, 0x1b); + gc0329_write_register(ViPipe, 0x67, 0x2b); + gc0329_write_register(ViPipe, 0x68, 0x3d); + gc0329_write_register(ViPipe, 0x69, 0x50); + gc0329_write_register(ViPipe, 0x6a, 0x60); + gc0329_write_register(ViPipe, 0x6b, 0x80); + gc0329_write_register(ViPipe, 0x6c, 0xa0); + gc0329_write_register(ViPipe, 0x6d, 0xc0); + gc0329_write_register(ViPipe, 0x6e, 0xe0); + gc0329_write_register(ViPipe, 0x6f, 0xff); + + gc0329_write_register(ViPipe, 0xfe, 0x00); + gc0329_write_register(ViPipe, 0xb3, 0x44); + gc0329_write_register(ViPipe, 0xb4, 0xfd); + gc0329_write_register(ViPipe, 0xb5, 0x02); + gc0329_write_register(ViPipe, 0xb6, 0xfa); + gc0329_write_register(ViPipe, 0xb7, 0x48); + gc0329_write_register(ViPipe, 0xb8, 0xf0); + gc0329_write_register(ViPipe, 0x50, 0x01); + + gc0329_write_register(ViPipe, 0xfe, 0x00); + gc0329_write_register(ViPipe, 0xd0, 0x40); + gc0329_write_register(ViPipe, 0xd1, 0x28); + gc0329_write_register(ViPipe, 0xd2, 0x28); + gc0329_write_register(ViPipe, 0xd3, 0x40); + gc0329_write_register(ViPipe, 0xd5, 0x00); + gc0329_write_register(ViPipe, 0xdd, 0x14); + gc0329_write_register(ViPipe, 0xde, 0x34); + + gc0329_write_register(ViPipe, 0xfe, 0x01); + gc0329_write_register(ViPipe, 0x10, 0x40); + gc0329_write_register(ViPipe, 0x11, 0x21); + gc0329_write_register(ViPipe, 0x12, 0x13); + gc0329_write_register(ViPipe, 0x13, 0x50); + gc0329_write_register(ViPipe, 0x17, 0xa8); + gc0329_write_register(ViPipe, 0x1a, 0x21); + gc0329_write_register(ViPipe, 0x20, 0x31); + gc0329_write_register(ViPipe, 0x21, 0xc0); + gc0329_write_register(ViPipe, 0x22, 0x60); + gc0329_write_register(ViPipe, 0x3c, 0x50); + gc0329_write_register(ViPipe, 0x3d, 0x40); + gc0329_write_register(ViPipe, 0x3e, 0x45); + + gc0329_write_register(ViPipe, 0xfe, 0x01); + gc0329_write_register(ViPipe, 0x06, 0x12); + gc0329_write_register(ViPipe, 0x07, 0x06); + gc0329_write_register(ViPipe, 0x08, 0x9c); + gc0329_write_register(ViPipe, 0x09, 0xee); + gc0329_write_register(ViPipe, 0x50, 0xfc); + gc0329_write_register(ViPipe, 0x51, 0x28); + gc0329_write_register(ViPipe, 0x52, 0x10); + gc0329_write_register(ViPipe, 0x53, 0x20); + gc0329_write_register(ViPipe, 0x54, 0x12); + gc0329_write_register(ViPipe, 0x55, 0x16); + gc0329_write_register(ViPipe, 0x56, 0x30); + gc0329_write_register(ViPipe, 0x58, 0x60); + gc0329_write_register(ViPipe, 0x59, 0x08); + gc0329_write_register(ViPipe, 0x5a, 0x02); + gc0329_write_register(ViPipe, 0x5b, 0x63); + gc0329_write_register(ViPipe, 0x5c, 0x35); + gc0329_write_register(ViPipe, 0x5d, 0x72); + gc0329_write_register(ViPipe, 0x5e, 0x11); + gc0329_write_register(ViPipe, 0x5f, 0x40); + gc0329_write_register(ViPipe, 0x60, 0x40); + gc0329_write_register(ViPipe, 0x61, 0xc8); + gc0329_write_register(ViPipe, 0x62, 0xa0); + gc0329_write_register(ViPipe, 0x63, 0x40); + gc0329_write_register(ViPipe, 0x64, 0x50); + gc0329_write_register(ViPipe, 0x65, 0x98); + gc0329_write_register(ViPipe, 0x66, 0xfa); + gc0329_write_register(ViPipe, 0x67, 0x80); + gc0329_write_register(ViPipe, 0x68, 0x60); + gc0329_write_register(ViPipe, 0x69, 0x90); + gc0329_write_register(ViPipe, 0x6a, 0x40); + gc0329_write_register(ViPipe, 0x6b, 0x39); + gc0329_write_register(ViPipe, 0x6c, 0x30); + gc0329_write_register(ViPipe, 0x6d, 0x60); + gc0329_write_register(ViPipe, 0x6e, 0x41); + gc0329_write_register(ViPipe, 0x70, 0x10); + gc0329_write_register(ViPipe, 0x71, 0x00); + gc0329_write_register(ViPipe, 0x72, 0x10); + gc0329_write_register(ViPipe, 0x73, 0x40); + gc0329_write_register(ViPipe, 0x80, 0x60); + gc0329_write_register(ViPipe, 0x81, 0x50); + gc0329_write_register(ViPipe, 0x82, 0x42); + gc0329_write_register(ViPipe, 0x83, 0x40); + gc0329_write_register(ViPipe, 0x84, 0x40); + gc0329_write_register(ViPipe, 0x85, 0x40); + gc0329_write_register(ViPipe, 0x74, 0x40); + gc0329_write_register(ViPipe, 0x75, 0x58); + gc0329_write_register(ViPipe, 0x76, 0x24); + gc0329_write_register(ViPipe, 0x77, 0x40); + gc0329_write_register(ViPipe, 0x78, 0x20); + gc0329_write_register(ViPipe, 0x79, 0x60); + gc0329_write_register(ViPipe, 0x7a, 0x58); + gc0329_write_register(ViPipe, 0x7b, 0x20); + gc0329_write_register(ViPipe, 0x7c, 0x30); + gc0329_write_register(ViPipe, 0x7d, 0x35); + gc0329_write_register(ViPipe, 0x7e, 0x10); + gc0329_write_register(ViPipe, 0x7f, 0x08); + + gc0329_write_register(ViPipe, 0x9c, 0x00); + gc0329_write_register(ViPipe, 0x9e, 0xc0); + gc0329_write_register(ViPipe, 0x9f, 0x40); + + gc0329_write_register(ViPipe, 0xd0, 0x00); + gc0329_write_register(ViPipe, 0xd2, 0x2c); + gc0329_write_register(ViPipe, 0xd3, 0x80); + + gc0329_write_register(ViPipe, 0xfe, 0x01); + gc0329_write_register(ViPipe, 0xc0, 0x0b); + gc0329_write_register(ViPipe, 0xc1, 0x07); + gc0329_write_register(ViPipe, 0xc2, 0x05); + gc0329_write_register(ViPipe, 0xc6, 0x0b); + gc0329_write_register(ViPipe, 0xc7, 0x07); + gc0329_write_register(ViPipe, 0xc8, 0x05); + gc0329_write_register(ViPipe, 0xba, 0x39); + gc0329_write_register(ViPipe, 0xbb, 0x24); + gc0329_write_register(ViPipe, 0xbc, 0x23); + gc0329_write_register(ViPipe, 0xb4, 0x39); + gc0329_write_register(ViPipe, 0xb5, 0x24); + gc0329_write_register(ViPipe, 0xb6, 0x23); + gc0329_write_register(ViPipe, 0xc3, 0x00); + gc0329_write_register(ViPipe, 0xc4, 0x00); + gc0329_write_register(ViPipe, 0xc5, 0x00); + gc0329_write_register(ViPipe, 0xc9, 0x00); + gc0329_write_register(ViPipe, 0xca, 0x00); + gc0329_write_register(ViPipe, 0xcb, 0x00); + gc0329_write_register(ViPipe, 0xbd, 0x2b); + gc0329_write_register(ViPipe, 0xbe, 0x00); + gc0329_write_register(ViPipe, 0xbf, 0x00); + gc0329_write_register(ViPipe, 0xb7, 0x09); + gc0329_write_register(ViPipe, 0xb8, 0x00); + gc0329_write_register(ViPipe, 0xb9, 0x00); + gc0329_write_register(ViPipe, 0xa8, 0x31); + gc0329_write_register(ViPipe, 0xa9, 0x23); + gc0329_write_register(ViPipe, 0xaa, 0x20); + gc0329_write_register(ViPipe, 0xab, 0x31); + gc0329_write_register(ViPipe, 0xac, 0x23); + gc0329_write_register(ViPipe, 0xad, 0x20); + gc0329_write_register(ViPipe, 0xae, 0x31); + gc0329_write_register(ViPipe, 0xaf, 0x23); + gc0329_write_register(ViPipe, 0xb0, 0x20); + gc0329_write_register(ViPipe, 0xb1, 0x31); + gc0329_write_register(ViPipe, 0xb2, 0x23); + gc0329_write_register(ViPipe, 0xb3, 0x20); + gc0329_write_register(ViPipe, 0xa4, 0x00); + gc0329_write_register(ViPipe, 0xa5, 0x00); + gc0329_write_register(ViPipe, 0xa6, 0x00); + gc0329_write_register(ViPipe, 0xa7, 0x00); + gc0329_write_register(ViPipe, 0xa1, 0x3c); + gc0329_write_register(ViPipe, 0xa2, 0x50); + gc0329_write_register(ViPipe, 0xfe, 0x00); + + gc0329_write_register(ViPipe, 0x05, 0x02); + gc0329_write_register(ViPipe, 0x06, 0x2c); + gc0329_write_register(ViPipe, 0x07, 0x00); + gc0329_write_register(ViPipe, 0x08, 0xb8); + gc0329_write_register(ViPipe, 0xfe, 0x01); + gc0329_write_register(ViPipe, 0x29, 0x00); + gc0329_write_register(ViPipe, 0x2a, 0x60); + gc0329_write_register(ViPipe, 0x2b, 0x02); + gc0329_write_register(ViPipe, 0x2c, 0xa0); + gc0329_write_register(ViPipe, 0x2d, 0x03); + gc0329_write_register(ViPipe, 0x2e, 0x00); + gc0329_write_register(ViPipe, 0x2f, 0x03); + gc0329_write_register(ViPipe, 0x30, 0xc0); + gc0329_write_register(ViPipe, 0x31, 0x05); + gc0329_write_register(ViPipe, 0x32, 0x40); + gc0329_write_register(ViPipe, 0xfe, 0x00); + + gc0329_write_register(ViPipe, 0x44, 0xa2); + gc0329_write_register(ViPipe, 0xf0, 0x07); + gc0329_write_register(ViPipe, 0xf1, 0x01); + + delay_ms(50); + + printf("ViPipe:%d,===GC0329 480P 10fps YUV Init OK!===\n", ViPipe); +} + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1054/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1054/Makefile new file mode 100644 index 00000000..eb95cf43 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1054/gc1054_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1054/gc1054_cmos.c new file mode 100644 index 00000000..bac19494 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1054/gc1054_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1054/gc1054_cmos_ex.h new file mode 100644 index 00000000..da266e89 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1054/gc1054_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1054/gc1054_cmos_param.h new file mode 100644 index 00000000..1d49ef7a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1054/gc1054_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1054/gc1054_sensor_ctl.c new file mode 100644 index 00000000..82822b86 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084/Makefile new file mode 100644 index 00000000..874b037a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084/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_gc1084.a +TARGET_SO = $(MW_LIB)/libsns_gc1084.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084/gc1084_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084/gc1084_cmos.c new file mode 100644 index 00000000..f9f0c703 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084/gc1084_cmos.c @@ -0,0 +1,977 @@ +#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 "gc1084_cmos_ex.h" +#include "gc1084_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 GC1084_ID 1084 + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc1084[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC1084_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc1084[dev]) +#define GC1084_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc1084[dev] = pstCtx) +#define GC1084_SENSOR_RESET_CTX(dev) (g_pastGc1084[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc1084_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +GC1084_STATE_S g_astGc1084_State[VI_MAX_PIPE_NUM] = { {0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc1084_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +CVI_U16 g_au16Gc1084_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Gc1084_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); +/*****Gc1084 Lines Range*****/ +#define GC1084_FULL_LINES_MAX (17119) // 0x3FFF(Max VB) + 720 + 16 + +/*****Gc1084 Register Address*****/ +#define GC1084_EXP_H_ADDR 0x0d03 +#define GC1084_EXP_L_ADDR 0x0d04 + +#define GC1084_AGAIN_M_ADDR 0x00d1 +#define GC1084_AGAIN_L_ADDR 0x00d0 +#define GC1084_AGAIN_REG_0x031D 0x031d +#define GC1084_AGAIN_H_ADDR 0x0dc1 +#define GC1084_COL_AGAIN_H_ADDR 0x00b8 +#define GC1084_COL_AGAIN_L_ADDR 0x00b9 +#define GC1084_AGAIN_REG_0x0155 0x0155 + +#define GC1084_DGAIN_H_ADDR 0x00b1 +#define GC1084_DGAIN_L_ADDR 0x00b2 + +#define GC1084_VTS_H_ADDR 0x0d41 +#define GC1084_VTS_L_ADDR 0x0d42 + +#define GC1084_FLIP_MIRROR_ADDR1 0x0015 +#define GC1084_FLIP_MIRROR_ADDR2 0x0d15 + +#define GC1084_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 GC1084_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc1084_mode; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC1084_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 = 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; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_stGc1084_mode.u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_stGc1084_mode.f32MaxFps; + f32MinFps = g_stGc1084_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 > GC1084_FULL_LINES_MAX) ? GC1084_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; + + GC1084_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[21][6] = { + /* [reg] 0x00d1, 0x00d0, 0x0dc1, 0x00b8, 0x00b9, 0x155 + * [name] AGAIN_M, AGAIN_L, AGAIN_H, COLGA_H, COLGA_L, REG_0x0155 + */ + {0x00, 0x00, 0x00, 0x01, 0x00, 0x00}, + // {0x0A, 0x00, 0x00, 0x01, 0x0c, 0x00}, + // {0x00, 0x01, 0x00, 0x01, 0x1a, 0x00}, + // {0x0A, 0x01, 0x00, 0x01, 0x2a, 0x00}, + // {0x00, 0x02, 0x00, 0x02, 0x00, 0x00}, + {0x0A, 0x02, 0x00, 0x02, 0x18, 0x00}, + {0x00, 0x03, 0x00, 0x02, 0x33, 0x00}, + {0x0A, 0x03, 0x00, 0x03, 0x14, 0x00}, + {0x00, 0x04, 0x00, 0x04, 0x00, 0x02}, + {0x0A, 0x04, 0x00, 0x04, 0x2f, 0x02}, + {0x00, 0x05, 0x00, 0x05, 0x26, 0x02}, + {0x0A, 0x05, 0x00, 0x06, 0x29, 0x02}, + {0x00, 0x06, 0x00, 0x08, 0x00, 0x02}, + {0x0A, 0x06, 0x00, 0x09, 0x1f, 0x04}, + {0x12, 0x46, 0x00, 0x0b, 0x0d, 0x04}, + {0x19, 0x66, 0x00, 0x0d, 0x12, 0x06}, + {0x00, 0x04, 0x01, 0x10, 0x00, 0x06}, + {0x0A, 0x04, 0x01, 0x12, 0x3e, 0x08}, + {0x00, 0x05, 0x01, 0x16, 0x1a, 0x0a}, + {0x0A, 0x05, 0x01, 0x1a, 0x23, 0x0c}, + {0x00, 0x06, 0x01, 0x20, 0x00, 0x0c}, + {0x0A, 0x06, 0x01, 0x25, 0x3b, 0x0f}, + {0x12, 0x46, 0x01, 0x2c, 0x33, 0x12}, + {0x19, 0x66, 0x01, 0x35, 0x06, 0x14}, + {0x20, 0x06, 0x01, 0x3f, 0x3f, 0x15}, +}; +//1024-2048 gain use ispdgain +static CVI_U32 gain_table[21] = { + 1024, + // 1168, 1440, 1696, 2014, + 2432, 2864, 3392, + 4096, 4848, 5728, 6800, 8192, 9712, 11472, 13584, + 16384, 19408, 22944, 27184, 32768, 38832, 45872, 54368, + 65536 +}; +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 + if (*pu32AgainLin < 2432) { + *pu32AgainDb = *pu32AgainLin = 1024; + } else { + *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) +{ + 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; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + int i, total; + + total = sizeof(gain_table) / sizeof(CVI_U32); + + GC1084_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 */ + /* To kepp the linearity. we assume AE algo adjusts the dgain only when the again reachs the maximum value */ + if (pu32Again[0] < gain_table[total - 1]) { + for (i = 1; i < total; i++) { + if (*pu32Again < gain_table[i]) + break; + } + i--; + // find the pregain + u32Dgain = pu32Again[0] * 64 / gain_table[i]; + u32Again = i; + } else { + // find the pregain + u32Dgain = pu32Again[0] * 64 / gain_table[total - 1]; + u32Again = total - 1; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_M].u32Data = regValTable[u32Again][0]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][1]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REG_0x031D_0x2E].u32Data = 0x2e; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H].u32Data = regValTable[u32Again][2]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REG_0x031D_0x28].u32Data = 0x28; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][3]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][4]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REG_0x0155].u32Data = regValTable[u32Again][5]; + + 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); + + 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 GC1084_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc1084_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; + + GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = GC1084_MODE_1280X720P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc1084_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); + GC1084_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_aunGc1084_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 = gc1084_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc1084_addr_byte; + pstI2c_data[i].u32DataByteNum = gc1084_data_byte; + } + + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC1084_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC1084_EXP_L_ADDR; + + pstI2c_data[LINEAR_AGAIN_M].u32RegAddr = GC1084_AGAIN_M_ADDR; + pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC1084_AGAIN_L_ADDR; + pstI2c_data[LINEAR_AGAIN_REG_0x031D_0x2E].u32RegAddr = GC1084_AGAIN_REG_0x031D; + pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = GC1084_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_REG_0x031D_0x28].u32RegAddr = GC1084_AGAIN_REG_0x031D; + pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC1084_COL_AGAIN_H_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC1084_COL_AGAIN_L_ADDR; + pstI2c_data[LINEAR_AGAIN_REG_0x0155].u32RegAddr = GC1084_AGAIN_REG_0x0155; + pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = GC1084_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = GC1084_DGAIN_L_ADDR; + + pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC1084_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC1084_VTS_L_ADDR; + + pstI2c_data[LINEAR_FLIP_MIRROR1].u32RegAddr = GC1084_FLIP_MIRROR_ADDR1; + pstI2c_data[LINEAR_FLIP_MIRROR2].u32RegAddr = GC1084_FLIP_MIRROR_ADDR2; + + 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, 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_M) && (i <= LINEAR_DGAIN_L)) + gainsUpdate = 1; + + if (i <= LINEAR_EXP_L) + expUpdate = 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_M].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_REG_0x031D_0x2E].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_REG_0x031D_0x28].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_REG_0x0155].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L].bUpdate = CVI_TRUE; + } + if (expUpdate) { + 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; + } + + 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_MIRROR1].bDropFrm = CVI_FALSE; + pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR2].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); + GC1084_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 (GC1084_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC1084_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 = 0; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC1084_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_aeGc1084_MirrorFip[ViPipe] != eSnsMirrorFlip) { + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + value = 0; + break; + case ISP_SNS_MIRROR: + value = 2; + break; + case ISP_SNS_FLIP: + value = 1; + break; + case ISP_SNS_MIRROR_FLIP: + value = 3; + break; + default: + return; + } + + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR1].u32Data = value; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR2].u32Data = value; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR1].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR2].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR1].u8DropFrmNum = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR2].u8DropFrmNum = 1; + + g_aeGc1084_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC1084_MODE_1280X720P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc1084_mode.u32VtsDef; + pstSnsState->au32FL[0] = g_stGc1084_mode.u32VtsDef; + pstSnsState->au32FL[1] = g_stGc1084_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; + + GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc1084_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_stGc1084_mode.stImg.stSnsSize.u32Width; + pstRxAttr->img_size.height = g_stGc1084_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 = &gc1084_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + 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 = gc1084_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc1084_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 gc1084_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc1084_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC1084_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)); + + GC1084_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC1084_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC1084_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 = GC1084_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, GC1084_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, GC1084_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, GC1084_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_au16Gc1084_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Gc1084_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc1084_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc1084_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc1084_standby, + .pfnRestart = gc1084_restart, + .pfnWriteReg = gc1084_write_register, + .pfnReadReg = gc1084_read_register, + .pfnSetBusInfo = gc1084_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 = sensor_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084/gc1084_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084/gc1084_cmos_ex.h new file mode 100644 index 00000000..4edd6ceb --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084/gc1084_cmos_ex.h @@ -0,0 +1,98 @@ +#ifndef __GC1084_CMOS_EX_H_ +#define __GC1084_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 gc1084_linear_regs_e { + LINEAR_EXP_H, + LINEAR_EXP_L, + + LINEAR_AGAIN_M, + LINEAR_AGAIN_L, + LINEAR_AGAIN_REG_0x031D_0x2E, + LINEAR_AGAIN_H, + LINEAR_AGAIN_REG_0x031D_0x28, + LINEAR_COL_AGAIN_H, + LINEAR_COL_AGAIN_L, + LINEAR_AGAIN_REG_0x0155, + + LINEAR_DGAIN_H, + LINEAR_DGAIN_L, + + LINEAR_VTS_H, + LINEAR_VTS_L, + + LINEAR_FLIP_MIRROR1, + LINEAR_FLIP_MIRROR2, + + LINEAR_REGS_NUM +}; + + +typedef enum _GC1084_MODE_E { + GC1084_MODE_1280X720P30 = 0, + GC1084_MODE_NUM +} GC1084_SLAVE_MODE_E; + +typedef struct _GC1084_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC1084_STATE_S; + +typedef struct _GC1084_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]; +} GC1084_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc1084[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc1084_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc1084_MirrorFip[VI_MAX_PIPE_NUM]; +extern const CVI_U8 gc1084_i2c_addr; +extern const CVI_U32 gc1084_addr_byte; +extern const CVI_U32 gc1084_data_byte; +extern void gc1084_init(VI_PIPE ViPipe); +extern void gc1084_exit(VI_PIPE ViPipe); +extern void gc1084_standby(VI_PIPE ViPipe); +extern void gc1084_restart(VI_PIPE ViPipe); +extern int gc1084_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc1084_read_register(VI_PIPE ViPipe, int addr); +extern int gc1084_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC1084_CMOS_EX_H_ */ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084/gc1084_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084/gc1084_cmos_param.h new file mode 100644 index 00000000..5ff2d57f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084/gc1084_cmos_param.h @@ -0,0 +1,219 @@ +#ifndef __GC1084_CMOS_PARAM_H_ +#define __GC1084_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 "gc1084_cmos_ex.h" + +static const GC1084_MODE_S g_stGc1084_mode = { + .name = "1280X720P30", + .stImg = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.31, /* 750 * 30 / 0xFFFF */ + .u32HtsDef = 2200, + .u32VtsDef = 746, /* WIN_H + VB + 16 */ + .stExp = { + .u16Min = 1, + .u16Max = 746 - 1, /* VtsDef - 1*/ + .u16Def = 100, + .u16Step = 1, + }, + .stAgain = { + .u32Min = 1024, + .u32Max = 64 * 1024, + .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 = {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 gc1084_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, -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 /* __GC1084_CMOS_PARAM_H_ */ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084/gc1084_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084/gc1084_sensor_ctl.c new file mode 100644 index 00000000..5065c9d9 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084/gc1084_sensor_ctl.c @@ -0,0 +1,332 @@ +#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 "gc1084_cmos_ex.h" + +#define GC1084_CHIP_ID_ADDR_H 0x03f0 +#define GC1084_CHIP_ID_ADDR_L 0x03f1 +#define GC1084_CHIP_ID 0x1084 + +static void gc1084_linear_720p30_init(VI_PIPE ViPipe); + +const CVI_U8 gc1084_i2c_addr = 0x37;//0x42 +const CVI_U32 gc1084_addr_byte = 2; +const CVI_U32 gc1084_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc1084_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc1084_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, gc1084_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 gc1084_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 gc1084_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 (gc1084_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc1084_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, gc1084_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (gc1084_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 gc1084_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (gc1084_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (gc1084_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc1084_addr_byte + gc1084_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 gc1084_standby(VI_PIPE ViPipe) +{ + UNUSED(ViPipe); + printf("%s\n", __func__); +} + +void gc1084_restart(VI_PIPE ViPipe) +{ + UNUSED(ViPipe); + printf("%s\n", __func__); +} + + +int gc1084_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc1084_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc1084_read_register(ViPipe, GC1084_CHIP_ID_ADDR_H); + nVal2 = gc1084_read_register(ViPipe, GC1084_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)) != GC1084_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc1084_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc1084[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc1084_write_register(ViPipe, + g_pastGc1084[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc1084[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void gc1084_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode = g_pastGc1084[ViPipe]->enWDRMode; + + gc1084_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n"); + } else { + gc1084_linear_720p30_init(ViPipe); + } + g_pastGc1084[ViPipe]->bInit = CVI_TRUE; +} + +void gc1084_exit(VI_PIPE ViPipe) +{ + gc1084_i2c_exit(ViPipe); +} + +static void gc1084_linear_720p30_init(VI_PIPE ViPipe) +{ + gc1084_write_register(ViPipe, 0x03fe, 0xf0); + gc1084_write_register(ViPipe, 0x03fe, 0xf0); + gc1084_write_register(ViPipe, 0x03fe, 0xf0); + gc1084_write_register(ViPipe, 0x03fe, 0x00); + gc1084_write_register(ViPipe, 0x03f2, 0x00); + gc1084_write_register(ViPipe, 0x03f3, 0x00); + gc1084_write_register(ViPipe, 0x03f4, 0x36); + gc1084_write_register(ViPipe, 0x03f5, 0xc0); + gc1084_write_register(ViPipe, 0x03f6, 0x13); + gc1084_write_register(ViPipe, 0x03f7, 0x01); + gc1084_write_register(ViPipe, 0x03f8, 0x2c); + gc1084_write_register(ViPipe, 0x03f9, 0x21); + gc1084_write_register(ViPipe, 0x03fc, 0xae); + gc1084_write_register(ViPipe, 0x0d05, 0x08); + gc1084_write_register(ViPipe, 0x0d06, 0x98); + gc1084_write_register(ViPipe, 0x0d08, 0x10); + gc1084_write_register(ViPipe, 0x0d0a, 0x02); + gc1084_write_register(ViPipe, 0x000c, 0x03); + gc1084_write_register(ViPipe, 0x0d0d, 0x02); + gc1084_write_register(ViPipe, 0x0d0e, 0xd4); + gc1084_write_register(ViPipe, 0x000f, 0x05); + gc1084_write_register(ViPipe, 0x0010, 0x08); + gc1084_write_register(ViPipe, 0x0017, 0x08); + gc1084_write_register(ViPipe, 0x0d73, 0x92); + gc1084_write_register(ViPipe, 0x0076, 0x00); + gc1084_write_register(ViPipe, 0x0d76, 0x00); + gc1084_write_register(ViPipe, 0x0d41, 0x02); + gc1084_write_register(ViPipe, 0x0d42, 0xee); + gc1084_write_register(ViPipe, 0x0d7a, 0x0a); + gc1084_write_register(ViPipe, 0x006b, 0x18); + gc1084_write_register(ViPipe, 0x0db0, 0x9d); + gc1084_write_register(ViPipe, 0x0db1, 0x00); + gc1084_write_register(ViPipe, 0x0db2, 0xac); + gc1084_write_register(ViPipe, 0x0db3, 0xd5); + gc1084_write_register(ViPipe, 0x0db4, 0x00); + gc1084_write_register(ViPipe, 0x0db5, 0x97); + gc1084_write_register(ViPipe, 0x0db6, 0x09); + gc1084_write_register(ViPipe, 0x00d2, 0xfc); + gc1084_write_register(ViPipe, 0x0d19, 0x31); + gc1084_write_register(ViPipe, 0x0d20, 0x40); + gc1084_write_register(ViPipe, 0x0d25, 0xcb); + gc1084_write_register(ViPipe, 0x0d27, 0x03); + gc1084_write_register(ViPipe, 0x0d29, 0x40); + gc1084_write_register(ViPipe, 0x0d43, 0x20); + gc1084_write_register(ViPipe, 0x0058, 0x60); + gc1084_write_register(ViPipe, 0x00d6, 0x66); + gc1084_write_register(ViPipe, 0x00d7, 0x19); + gc1084_write_register(ViPipe, 0x0093, 0x02); + gc1084_write_register(ViPipe, 0x00d9, 0x14); + gc1084_write_register(ViPipe, 0x00da, 0xc1); + gc1084_write_register(ViPipe, 0x0d2a, 0x00); + gc1084_write_register(ViPipe, 0x0d28, 0x04); + gc1084_write_register(ViPipe, 0x0dc2, 0x84); + gc1084_write_register(ViPipe, 0x0050, 0x30); + gc1084_write_register(ViPipe, 0x0080, 0x07); + gc1084_write_register(ViPipe, 0x008c, 0x05); + gc1084_write_register(ViPipe, 0x008d, 0xa8); + gc1084_write_register(ViPipe, 0x0077, 0x01); + gc1084_write_register(ViPipe, 0x0078, 0xee); + gc1084_write_register(ViPipe, 0x0079, 0x02); + gc1084_write_register(ViPipe, 0x0067, 0xc0); + gc1084_write_register(ViPipe, 0x0054, 0xff); + gc1084_write_register(ViPipe, 0x0055, 0x02); + gc1084_write_register(ViPipe, 0x0056, 0x00); + gc1084_write_register(ViPipe, 0x0057, 0x04); + gc1084_write_register(ViPipe, 0x005a, 0xff); + gc1084_write_register(ViPipe, 0x005b, 0x07); + gc1084_write_register(ViPipe, 0x00d5, 0x03); + gc1084_write_register(ViPipe, 0x0102, 0xa9); + gc1084_write_register(ViPipe, 0x0d03, 0x02); + gc1084_write_register(ViPipe, 0x0d04, 0xd0); + gc1084_write_register(ViPipe, 0x007a, 0x60); + gc1084_write_register(ViPipe, 0x04e0, 0xff); + gc1084_write_register(ViPipe, 0x0414, 0x75); + gc1084_write_register(ViPipe, 0x0415, 0x75); + gc1084_write_register(ViPipe, 0x0416, 0x75); + gc1084_write_register(ViPipe, 0x0417, 0x75); + gc1084_write_register(ViPipe, 0x0122, 0x00); + gc1084_write_register(ViPipe, 0x0121, 0x80); + gc1084_write_register(ViPipe, 0x0428, 0x10); + gc1084_write_register(ViPipe, 0x0429, 0x10); + gc1084_write_register(ViPipe, 0x042a, 0x10); + gc1084_write_register(ViPipe, 0x042b, 0x10); + gc1084_write_register(ViPipe, 0x042c, 0x14); + gc1084_write_register(ViPipe, 0x042d, 0x14); + gc1084_write_register(ViPipe, 0x042e, 0x18); + gc1084_write_register(ViPipe, 0x042f, 0x18); + gc1084_write_register(ViPipe, 0x0430, 0x05); + gc1084_write_register(ViPipe, 0x0431, 0x05); + gc1084_write_register(ViPipe, 0x0432, 0x05); + gc1084_write_register(ViPipe, 0x0433, 0x05); + gc1084_write_register(ViPipe, 0x0434, 0x05); + gc1084_write_register(ViPipe, 0x0435, 0x05); + gc1084_write_register(ViPipe, 0x0436, 0x05); + gc1084_write_register(ViPipe, 0x0437, 0x05); + gc1084_write_register(ViPipe, 0x0153, 0x00); + gc1084_write_register(ViPipe, 0x0190, 0x01); + gc1084_write_register(ViPipe, 0x0192, 0x02); + gc1084_write_register(ViPipe, 0x0194, 0x04); + gc1084_write_register(ViPipe, 0x0195, 0x02); + gc1084_write_register(ViPipe, 0x0196, 0xd0); + gc1084_write_register(ViPipe, 0x0197, 0x05); + gc1084_write_register(ViPipe, 0x0198, 0x00); + gc1084_write_register(ViPipe, 0x0201, 0x23); + gc1084_write_register(ViPipe, 0x0202, 0x53); + gc1084_write_register(ViPipe, 0x0203, 0xce); + gc1084_write_register(ViPipe, 0x0208, 0x39); + gc1084_write_register(ViPipe, 0x0212, 0x06); + gc1084_write_register(ViPipe, 0x0213, 0x40); + gc1084_write_register(ViPipe, 0x0215, 0x12); + gc1084_write_register(ViPipe, 0x0229, 0x05); + gc1084_write_register(ViPipe, 0x023e, 0x98); + gc1084_write_register(ViPipe, 0x031e, 0x3e); + + gc1084_default_reg_init(ViPipe); + delay_ms(40); + printf("ViPipe:%d,===GC1084 720P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084_slave/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084_slave/Makefile new file mode 100644 index 00000000..ea572c80 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084_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_gc1084_slave.a +TARGET_SO = $(MW_LIB)/libsns_gc1084_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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084_slave/gc1084_slave_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084_slave/gc1084_slave_cmos.c new file mode 100644 index 00000000..3c040267 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084_slave/gc1084_slave_cmos.c @@ -0,0 +1,985 @@ +#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 "gc1084_slave_cmos_ex.h" +#include "gc1084_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 GC1084_SLAVE_ID 1084 + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc1084_Slave[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC1084_SLAVE_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc1084_Slave[dev]) +#define GC1084_SLAVE_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc1084_Slave[dev] = pstCtx) +#define GC1084_SLAVE_SENSOR_RESET_CTX(dev) (g_pastGc1084_Slave[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc1084_Slave_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +GC1084_SLAVE_STATE_S g_astGc1084_Slave_State[VI_MAX_PIPE_NUM] = { {0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc1084_Slave_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +CVI_U16 g_au16Gc1084_Slave_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Gc1084_Slave_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); +/*****Gc1084 Lines Range*****/ +#define GC1084_SLAVE_FULL_LINES_MAX (17119) // 0x3FFF(Max VB) + 720 + 16 + +/*****Gc1084 Register Address*****/ +#define GC1084_SLAVE_EXP_H_ADDR 0x0d03 +#define GC1084_SLAVE_EXP_L_ADDR 0x0d04 + +#define GC1084_SLAVE_AGAIN_M_ADDR 0x00d1 +#define GC1084_SLAVE_AGAIN_L_ADDR 0x00d0 +#define GC1084_SLAVE_AGAIN_REG_0x031D 0x031d +#define GC1084_SLAVE_AGAIN_H_ADDR 0x0dc1 +#define GC1084_SLAVE_COL_AGAIN_H_ADDR 0x00b8 +#define GC1084_SLAVE_COL_AGAIN_L_ADDR 0x00b9 +#define GC1084_SLAVE_AGAIN_REG_0x0155 0x0155 + +#define GC1084_SLAVE_DGAIN_H_ADDR 0x00b1 +#define GC1084_SLAVE_DGAIN_L_ADDR 0x00b2 + +#define GC1084_SLAVE_VTS_H_ADDR 0x0d41 +#define GC1084_SLAVE_VTS_L_ADDR 0x0042 +#define GC1084_SLAVE_VB_H_ADDR 0x0d79 +#define GC1084_SLAVE_VB_L_ADDR 0x0d7a + +#define GC1084_SLAVE_FLIP_MIRROR_ADDR1 0x0015 +#define GC1084_SLAVE_FLIP_MIRROR_ADDR2 0x0d15 + +#define GC1084_SLAVE_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 GC1084_SLAVE_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc1084_Slave_mode; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC1084_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 = 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); + GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_stGc1084_Slave_mode.u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_stGc1084_Slave_mode.f32MaxFps; + f32MinFps = g_stGc1084_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 > GC1084_SLAVE_FULL_LINES_MAX) ? GC1084_SLAVE_FULL_LINES_MAX : u32VMAX; + u32VB = u32VMAX - 720 - 16;//vts - win_h -16 + + pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF); + 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; + + GC1084_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][6] = { + /* [reg] 0x00d1, 0x00d0, 0x0dc1, 0x00b8, 0x00b9, 0x155 + * [name] AGAIN_M AGAIN_L AGAIN_H COLGA_H COLGA_L REG_0x0155 + */ + {0x00, 0x00, 0x00, 0x01, 0x00, 0x00}, + {0x0A, 0x00, 0x00, 0x01, 0x0c, 0x00}, + {0x00, 0x01, 0x00, 0x01, 0x1a, 0x00}, + {0x0A, 0x01, 0x00, 0x01, 0x2a, 0x00}, + {0x00, 0x02, 0x00, 0x02, 0x00, 0x00}, + {0x0A, 0x02, 0x00, 0x02, 0x18, 0x00}, + {0x00, 0x03, 0x00, 0x02, 0x33, 0x00}, + {0x0A, 0x03, 0x00, 0x03, 0x14, 0x00}, + {0x00, 0x04, 0x00, 0x04, 0x00, 0x02}, + {0x0A, 0x04, 0x00, 0x04, 0x2f, 0x02}, + {0x00, 0x05, 0x00, 0x05, 0x26, 0x02}, + {0x0A, 0x05, 0x00, 0x06, 0x29, 0x02}, + {0x00, 0x06, 0x00, 0x08, 0x00, 0x02}, + {0x0A, 0x06, 0x00, 0x09, 0x1f, 0x04}, + {0x12, 0x46, 0x00, 0x0b, 0x0d, 0x04}, + {0x19, 0x66, 0x00, 0x0d, 0x12, 0x06}, + {0x00, 0x04, 0x01, 0x10, 0x00, 0x06}, + {0x0A, 0x04, 0x01, 0x12, 0x3e, 0x08}, + {0x00, 0x05, 0x01, 0x16, 0x1a, 0x0a}, + {0x0A, 0x05, 0x01, 0x1a, 0x23, 0x0c}, + {0x00, 0x06, 0x01, 0x20, 0x00, 0x0c}, + {0x0A, 0x06, 0x01, 0x25, 0x3b, 0x0f}, + {0x12, 0x46, 0x01, 0x2c, 0x33, 0x12}, + {0x19, 0x66, 0x01, 0x35, 0x06, 0x14}, + {0x20, 0x06, 0x01, 0x3f, 0x3f, 0x15}, +}; + +static CVI_U32 gain_table[25] = { + 1024, 1216, 1440, 1696, 2048, 2432, 2864, 3392, + 4096, 4848, 5728, 6800, 8192, 9712, 11472, 13584, + 16384, 19408, 22944, 27184, 32768, 38832, 45872, 54368, + 65536 +}; +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) +{ + 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; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + int i, total; + + total = sizeof(gain_table) / sizeof(CVI_U32); + + GC1084_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 */ + /* To kepp the linearity. we assume AE algo adjusts the dgain only when the again reachs the maximum value */ + if (pu32Again[0] < gain_table[total - 1]) { + for (i = 1; i < total; i++) { + if (*pu32Again < gain_table[i]) + break; + } + i--; + // find the pregain + u32Dgain = pu32Again[0] * 64 / gain_table[i]; + u32Again = i; + } else { + // find the pregain + u32Dgain = pu32Again[0] * 64 / gain_table[total - 1]; + u32Again = total - 1; + } + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_M].u32Data = regValTable[u32Again][0]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][1]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REG_0x031D_0x2E].u32Data = 0x2e; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H].u32Data = regValTable[u32Again][2]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REG_0x031D_0x28].u32Data = 0x28; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][3]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][4]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REG_0x0155].u32Data = regValTable[u32Again][5]; + + 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); + + 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 GC1084_SLAVE_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc1084_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; + + GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = GC1084_SLAVE_MODE_1280X720P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc1084_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); + GC1084_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_aunGc1084_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 = gc1084_slave_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc1084_slave_addr_byte; + pstI2c_data[i].u32DataByteNum = gc1084_slave_data_byte; + } + + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC1084_SLAVE_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC1084_SLAVE_EXP_L_ADDR; + + pstI2c_data[LINEAR_AGAIN_M].u32RegAddr = GC1084_SLAVE_AGAIN_M_ADDR; + pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC1084_SLAVE_AGAIN_L_ADDR; + pstI2c_data[LINEAR_AGAIN_REG_0x031D_0x2E].u32RegAddr = GC1084_SLAVE_AGAIN_REG_0x031D; + pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = GC1084_SLAVE_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_REG_0x031D_0x28].u32RegAddr = GC1084_SLAVE_AGAIN_REG_0x031D; + pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC1084_SLAVE_COL_AGAIN_H_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC1084_SLAVE_COL_AGAIN_L_ADDR; + pstI2c_data[LINEAR_AGAIN_REG_0x0155].u32RegAddr = GC1084_SLAVE_AGAIN_REG_0x0155; + pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = GC1084_SLAVE_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = GC1084_SLAVE_DGAIN_L_ADDR; + + pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC1084_SLAVE_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC1084_SLAVE_VTS_L_ADDR; + pstI2c_data[LINEAR_VB_H].u32RegAddr = GC1084_SLAVE_VB_H_ADDR; + pstI2c_data[LINEAR_VB_L].u32RegAddr = GC1084_SLAVE_VB_L_ADDR; + + pstI2c_data[LINEAR_FLIP_MIRROR1].u32RegAddr = GC1084_SLAVE_FLIP_MIRROR_ADDR1; + pstI2c_data[LINEAR_FLIP_MIRROR2].u32RegAddr = GC1084_SLAVE_FLIP_MIRROR_ADDR2; + + 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_M) && (i <= LINEAR_DGAIN_L)) + gainsUpdate = 1; + + if (i <= LINEAR_EXP_L) + expUpdate = 1; + + if ((i >= LINEAR_VTS_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_AGAIN_M].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_REG_0x031D_0x2E].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_REG_0x031D_0x28].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_REG_0x0155].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L].bUpdate = CVI_TRUE; + } + if (expUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_L].bUpdate = CVI_TRUE; + } + if (vbUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_VTS_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_VTS_L].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_MIRROR1].bUpdate == CVI_TRUE) && (pstI2c_data[LINEAR_FLIP_MIRROR2].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_MIRROR1].bDropFrm = CVI_FALSE; + pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR2].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); + GC1084_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 (GC1084_SLAVE_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC1084_SLAVE_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 = 0; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC1084_SLAVE_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_aeGc1084_Slave_MirrorFip[ViPipe] != eSnsMirrorFlip) { + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + value = 0; + break; + case ISP_SNS_MIRROR: + value = 2; + break; + case ISP_SNS_FLIP: + value = 1; + break; + case ISP_SNS_MIRROR_FLIP: + value = 3; + break; + default: + return; + } + + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR1].u32Data = value; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR2].u32Data = value; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR1].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR2].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR1].u8DropFrmNum = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR2].u8DropFrmNum = 1; + + g_aeGc1084_Slave_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC1084_SLAVE_MODE_1280X720P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc1084_Slave_mode.u32VtsDef; + pstSnsState->au32FL[0] = g_stGc1084_Slave_mode.u32VtsDef; + pstSnsState->au32FL[1] = g_stGc1084_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; + + GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc1084_slave_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_stGc1084_Slave_mode.stImg.stSnsSize.u32Width; + pstRxAttr->img_size.height = g_stGc1084_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 = &gc1084_slave_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + 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 = gc1084_slave_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc1084_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 gc1084_slave_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc1084_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; + + GC1084_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)); + + GC1084_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; + + GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC1084_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 = GC1084_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, GC1084_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, GC1084_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, GC1084_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_au16Gc1084_Slave_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Gc1084_Slave_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsGc1084_Slave_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc1084_slave_standby, + .pfnRestart = gc1084_slave_restart, + .pfnWriteReg = gc1084_slave_write_register, + .pfnReadReg = gc1084_slave_read_register, + .pfnSetBusInfo = gc1084_slave_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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084_slave/gc1084_slave_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084_slave/gc1084_slave_cmos_ex.h new file mode 100644 index 00000000..021bf88b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084_slave/gc1084_slave_cmos_ex.h @@ -0,0 +1,99 @@ +#ifndef __GC1084_SLAVE_CMOS_EX_H_ +#define __GC1084_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 gc1084_slave_linear_regs_e { + LINEAR_EXP_H, + LINEAR_EXP_L, + + LINEAR_AGAIN_M, + LINEAR_AGAIN_L, + LINEAR_AGAIN_REG_0x031D_0x2E, + LINEAR_AGAIN_H, + LINEAR_AGAIN_REG_0x031D_0x28, + LINEAR_COL_AGAIN_H, + LINEAR_COL_AGAIN_L, + LINEAR_AGAIN_REG_0x0155, + + LINEAR_DGAIN_H, + LINEAR_DGAIN_L, + + LINEAR_VTS_H, + LINEAR_VTS_L, + LINEAR_VB_H, + LINEAR_VB_L, + + LINEAR_FLIP_MIRROR1, + LINEAR_FLIP_MIRROR2, + + LINEAR_REGS_NUM +}; + + +typedef enum _GC1084_SLAVE_MODE_E { + GC1084_SLAVE_MODE_1280X720P30 = 0, + GC1084_SLAVE_MODE_NUM +} GC1084_SLAVE_SLAVE_MODE_E; + +typedef struct _GC1084_SLAVE_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC1084_SLAVE_STATE_S; + +typedef struct _GC1084_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]; +} GC1084_SLAVE_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc1084_Slave[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc1084_Slave_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc1084_Slave_MirrorFip[VI_MAX_PIPE_NUM]; +extern const CVI_U8 gc1084_slave_i2c_addr; +extern const CVI_U32 gc1084_slave_addr_byte; +extern const CVI_U32 gc1084_slave_data_byte; +extern void gc1084_slave_init(VI_PIPE ViPipe); +extern void gc1084_slave_exit(VI_PIPE ViPipe); +extern void gc1084_slave_standby(VI_PIPE ViPipe); +extern void gc1084_slave_restart(VI_PIPE ViPipe); +extern int gc1084_slave_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc1084_slave_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC1084_SLAVE_CMOS_EX_H_ */ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084_slave/gc1084_slave_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084_slave/gc1084_slave_cmos_param.h new file mode 100644 index 00000000..b59c6403 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084_slave/gc1084_slave_cmos_param.h @@ -0,0 +1,219 @@ +#ifndef __GC1084_SLAVE_CMOS_PARAM_H_ +#define __GC1084_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 "gc1084_slave_cmos_ex.h" + +static const GC1084_SLAVE_MODE_S g_stGc1084_Slave_mode = { + .name = "1280X720P30", + .stImg = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.31, /* 750 * 30 / 0xFFFF */ + .u32HtsDef = 2200, + .u32VtsDef = 746, /* WIN_H + VB + 16 */ + .stExp = { + .u16Min = 1, + .u16Max = 746 - 1, /* VtsDef - 1*/ + .u16Def = 100, + .u16Step = 1, + }, + .stAgain = { + .u32Min = 1024, + .u32Max = 64 * 1024, + .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 = {0, 0, 0, 0, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#endif + }, + .stAuto = { + {0, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 }, + {0, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 }, + {0, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 }, + {0, 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 + {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 gc1084_slave_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, -1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 1, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 1, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC1084_SLAVE_CMOS_PARAM_H_ */ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084_slave/gc1084_slave_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084_slave/gc1084_slave_sensor_ctl.c new file mode 100644 index 00000000..1d2a9aff --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc1084_slave/gc1084_slave_sensor_ctl.c @@ -0,0 +1,271 @@ +#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 "gc1084_slave_cmos_ex.h" + +static void gc1084_slave_linear_720p30_init(VI_PIPE ViPipe); + +const CVI_U8 gc1084_slave_i2c_addr = 0x37;//0x42 +const CVI_U32 gc1084_slave_addr_byte = 2; +const CVI_U32 gc1084_slave_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc1084_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_aunGc1084_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, gc1084_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 gc1084_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 gc1084_slave_read_register(VI_PIPE ViPipe, int addr) +{ + /* TODO:*/ + UNUSED(ViPipe); + UNUSED(addr); + return CVI_SUCCESS; +} + + +int gc1084_slave_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (gc1084_slave_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (gc1084_slave_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc1084_slave_addr_byte + gc1084_slave_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + //ret = read(g_fd[ViPipe], buf, gc1084_slave_addr_byte + gc1084_slave_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 gc1084_slave_standby(VI_PIPE ViPipe) +{ + UNUSED(ViPipe); + printf("gc1084_slave_standby\n"); +} + +void gc1084_slave_restart(VI_PIPE ViPipe) +{ + UNUSED(ViPipe); + printf("gc1084_slave_restart\n"); +} + +void gc1084_slave_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc1084_Slave[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc1084_slave_write_register(ViPipe, + g_pastGc1084_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc1084_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void gc1084_slave_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode = g_pastGc1084_Slave[ViPipe]->enWDRMode; + + gc1084_slave_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n"); + } else { + gc1084_slave_linear_720p30_init(ViPipe); + } + g_pastGc1084_Slave[ViPipe]->bInit = CVI_TRUE; +} + +void gc1084_slave_exit(VI_PIPE ViPipe) +{ + gc1084_slave_i2c_exit(ViPipe); +} + +static void gc1084_slave_linear_720p30_init(VI_PIPE ViPipe) +{ + gc1084_slave_write_register(ViPipe, 0x03fe,0xf0); + gc1084_slave_write_register(ViPipe, 0x03fe,0xf0); + gc1084_slave_write_register(ViPipe, 0x03fe,0xf0); + gc1084_slave_write_register(ViPipe, 0x03fe,0x00); + gc1084_slave_write_register(ViPipe, 0x03f2,0x00); + gc1084_slave_write_register(ViPipe, 0x03f3,0x00); + gc1084_slave_write_register(ViPipe, 0x03f4,0x36); + gc1084_slave_write_register(ViPipe, 0x03f5,0xc0); + gc1084_slave_write_register(ViPipe, 0x03f6,0x13); + gc1084_slave_write_register(ViPipe, 0x03f7,0x01); + gc1084_slave_write_register(ViPipe, 0x03f8,0x2c); + gc1084_slave_write_register(ViPipe, 0x03f9,0x21); + gc1084_slave_write_register(ViPipe, 0x03fc,0xae); + gc1084_slave_write_register(ViPipe, 0x0d05,0x08); + gc1084_slave_write_register(ViPipe, 0x0d06,0x98); + gc1084_slave_write_register(ViPipe, 0x0d08,0x10); + gc1084_slave_write_register(ViPipe, 0x0d0a,0x02); + gc1084_slave_write_register(ViPipe, 0x000c,0x03); + gc1084_slave_write_register(ViPipe, 0x0d0d,0x02); + gc1084_slave_write_register(ViPipe, 0x0d0e,0xd4); + gc1084_slave_write_register(ViPipe, 0x000f,0x05); + gc1084_slave_write_register(ViPipe, 0x0010,0x08); + gc1084_slave_write_register(ViPipe, 0x0017,0x08); + gc1084_slave_write_register(ViPipe, 0x0d73,0x92); + gc1084_slave_write_register(ViPipe, 0x0076,0x00); + gc1084_slave_write_register(ViPipe, 0x0d76,0x00); + gc1084_slave_write_register(ViPipe, 0x0d41,0x02); + gc1084_slave_write_register(ViPipe, 0x0d42,0xee); + gc1084_slave_write_register(ViPipe, 0x0d7a,0x0a); + gc1084_slave_write_register(ViPipe, 0x006b,0x18); + gc1084_slave_write_register(ViPipe, 0x0db0,0x9d); + gc1084_slave_write_register(ViPipe, 0x0db1,0x00); + gc1084_slave_write_register(ViPipe, 0x0db2,0xac); + gc1084_slave_write_register(ViPipe, 0x0db3,0xd5); + gc1084_slave_write_register(ViPipe, 0x0db4,0x00); + gc1084_slave_write_register(ViPipe, 0x0db5,0x97); + gc1084_slave_write_register(ViPipe, 0x0db6,0x09); + gc1084_slave_write_register(ViPipe, 0x00d2,0xfc); + gc1084_slave_write_register(ViPipe, 0x0d19,0x31); + gc1084_slave_write_register(ViPipe, 0x0d20,0x40); + gc1084_slave_write_register(ViPipe, 0x0d25,0xcb); + gc1084_slave_write_register(ViPipe, 0x0d27,0x03); + gc1084_slave_write_register(ViPipe, 0x0d29,0x40); + gc1084_slave_write_register(ViPipe, 0x0d43,0x20); + gc1084_slave_write_register(ViPipe, 0x0058,0x60); + gc1084_slave_write_register(ViPipe, 0x00d6,0x66); + gc1084_slave_write_register(ViPipe, 0x00d7,0x19); + gc1084_slave_write_register(ViPipe, 0x0093,0x02); + gc1084_slave_write_register(ViPipe, 0x00d9,0x14); + gc1084_slave_write_register(ViPipe, 0x00da,0xc1); + gc1084_slave_write_register(ViPipe, 0x0d2a,0x00); + gc1084_slave_write_register(ViPipe, 0x0d28,0x04); + gc1084_slave_write_register(ViPipe, 0x0dc2,0x84); + gc1084_slave_write_register(ViPipe, 0x0050,0x30); + gc1084_slave_write_register(ViPipe, 0x0080,0x07); + gc1084_slave_write_register(ViPipe, 0x008c,0x05); + gc1084_slave_write_register(ViPipe, 0x008d,0xa8); + gc1084_slave_write_register(ViPipe, 0x0077,0x01); + gc1084_slave_write_register(ViPipe, 0x0078,0xee); + gc1084_slave_write_register(ViPipe, 0x0079,0x02); + gc1084_slave_write_register(ViPipe, 0x0067,0xc0); + gc1084_slave_write_register(ViPipe, 0x0054,0xff); + gc1084_slave_write_register(ViPipe, 0x0055,0x02); + gc1084_slave_write_register(ViPipe, 0x0056,0x00); + gc1084_slave_write_register(ViPipe, 0x0057,0x04); + gc1084_slave_write_register(ViPipe, 0x005a,0xff); + gc1084_slave_write_register(ViPipe, 0x005b,0x07); + gc1084_slave_write_register(ViPipe, 0x00d5,0x03); + gc1084_slave_write_register(ViPipe, 0x0102,0xa9); + gc1084_slave_write_register(ViPipe, 0x0d03,0x02); + gc1084_slave_write_register(ViPipe, 0x0d04,0xd0); + gc1084_slave_write_register(ViPipe, 0x007a,0x60); + gc1084_slave_write_register(ViPipe, 0x04e0,0xff); + gc1084_slave_write_register(ViPipe, 0x0414,0x75); + gc1084_slave_write_register(ViPipe, 0x0415,0x75); + gc1084_slave_write_register(ViPipe, 0x0416,0x75); + gc1084_slave_write_register(ViPipe, 0x0417,0x75); + gc1084_slave_write_register(ViPipe, 0x0122,0x00); + gc1084_slave_write_register(ViPipe, 0x0121,0x80); + gc1084_slave_write_register(ViPipe, 0x0428,0x10); + gc1084_slave_write_register(ViPipe, 0x0429,0x10); + gc1084_slave_write_register(ViPipe, 0x042a,0x10); + gc1084_slave_write_register(ViPipe, 0x042b,0x10); + gc1084_slave_write_register(ViPipe, 0x042c,0x14); + gc1084_slave_write_register(ViPipe, 0x042d,0x14); + gc1084_slave_write_register(ViPipe, 0x042e,0x18); + gc1084_slave_write_register(ViPipe, 0x042f,0x18); + gc1084_slave_write_register(ViPipe, 0x0430,0x05); + gc1084_slave_write_register(ViPipe, 0x0431,0x05); + gc1084_slave_write_register(ViPipe, 0x0432,0x05); + gc1084_slave_write_register(ViPipe, 0x0433,0x05); + gc1084_slave_write_register(ViPipe, 0x0434,0x05); + gc1084_slave_write_register(ViPipe, 0x0435,0x05); + gc1084_slave_write_register(ViPipe, 0x0436,0x05); + gc1084_slave_write_register(ViPipe, 0x0437,0x05); + gc1084_slave_write_register(ViPipe, 0x0153,0x00); + gc1084_slave_write_register(ViPipe, 0x0190,0x01); + gc1084_slave_write_register(ViPipe, 0x0192,0x02); + gc1084_slave_write_register(ViPipe, 0x0194,0x04); + gc1084_slave_write_register(ViPipe, 0x0195,0x02); + gc1084_slave_write_register(ViPipe, 0x0196,0xd0); + gc1084_slave_write_register(ViPipe, 0x0197,0x05); + gc1084_slave_write_register(ViPipe, 0x0198,0x00); + gc1084_slave_write_register(ViPipe, 0x0201,0x23); + gc1084_slave_write_register(ViPipe, 0x0202,0x53); + gc1084_slave_write_register(ViPipe, 0x0203,0xce); + gc1084_slave_write_register(ViPipe, 0x0208,0x39); + gc1084_slave_write_register(ViPipe, 0x0212,0x06); + gc1084_slave_write_register(ViPipe, 0x0213,0x40); + gc1084_slave_write_register(ViPipe, 0x0215,0x12); + gc1084_slave_write_register(ViPipe, 0x0229,0x05); + gc1084_slave_write_register(ViPipe, 0x023e,0x98); + gc1084_slave_write_register(ViPipe, 0x031e,0x3e); + + gc1084_slave_default_reg_init(ViPipe); + delay_ms(40); + printf("ViPipe:%d,===GC1084 720P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053/Makefile new file mode 100644 index 00000000..8566f11f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053/gc2053_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053/gc2053_cmos.c new file mode 100644 index 00000000..2e7ff915 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053/gc2053_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053/gc2053_cmos_ex.h new file mode 100644 index 00000000..05f2bb67 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053/gc2053_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053/gc2053_cmos_param.h new file mode 100644 index 00000000..d2824cf5 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053/gc2053_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053/gc2053_sensor_ctl.c new file mode 100644 index 00000000..007ac86b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_1L/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_1L/Makefile new file mode 100644 index 00000000..64bd2a95 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_1L/gc2053_1l_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_1L/gc2053_1l_cmos.c new file mode 100644 index 00000000..2c81bbc0 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_1L/gc2053_1l_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_1L/gc2053_1l_cmos_ex.h new file mode 100644 index 00000000..bbabb359 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_1L/gc2053_1l_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_1L/gc2053_1l_cmos_param.h new file mode 100644 index 00000000..9eece076 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_1L/gc2053_1l_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_1L/gc2053_1l_sensor_ctl.c new file mode 100644 index 00000000..328bb832 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_slave/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_slave/Makefile new file mode 100644 index 00000000..d6486940 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_slave/gc2053_slave_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_slave/gc2053_slave_cmos.c new file mode 100644 index 00000000..a18cff9e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_slave/gc2053_slave_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_slave/gc2053_slave_cmos_ex.h new file mode 100644 index 00000000..60b1f7e5 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_slave/gc2053_slave_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_slave/gc2053_slave_cmos_param.h new file mode 100644 index 00000000..983eac40 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_slave/gc2053_slave_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2053_slave/gc2053_slave_sensor_ctl.c new file mode 100644 index 00000000..52051502 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2083/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2083/Makefile new file mode 100644 index 00000000..25ce84b5 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2083/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_gc2083.a +TARGET_SO = $(MW_LIB)/libsns_gc2083.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2083/gc2083_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2083/gc2083_cmos.c new file mode 100644 index 00000000..abe7bf8c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2083/gc2083_cmos.c @@ -0,0 +1,962 @@ +#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 "gc2083_cmos_ex.h" +#include "gc2083_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 GC2083_ID 2083 +#define GC2083_I2C_ADDR_1 0x7e +#define GC2083_I2C_ADDR_2 0x37 +#define GC2083_I2C_ADDR_IS_VALID(addr) ((addr) == GC2083_I2C_ADDR_1 || (addr) == GC2083_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ***************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc2083[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC2083_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc2083[dev]) +#define GC2083_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc2083[dev] = pstCtx) +#define GC2083_SENSOR_RESET_CTX(dev) (g_pastGc2083[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc2083_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2083_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +CVI_U16 g_au16Gc2083_GainMode[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); +/*****Gc2083 Lines Range*****/ +#define GC2083_FULL_LINES_MAX (0x3fff) + +/*****Gc2083 Register Address*****/ +#define GC2083_EXP_H_ADDR 0x0d03 +#define GC2083_EXP_L_ADDR 0x0d04 +#define GC2083_SEXP_H_ADDR 0x0001 +#define GC2083_SEXP_L_ADDR 0x0002 + +#define GC2083_AGAIN_H_ADDR 0x0dc1// +#define GC2083_AGAIN_L_ADDR 0x00d0// +#define GC2083_COL_AGAIN_H_ADDR 0x00b8// +#define GC2083_COL_AGAIN_L_ADDR 0x00b9// + +#define GC2083_AGAIN_HOLD 0x031d//no + +#define GC2083_AGAIN_MAG1 0x0155 +#define GC2083_AGAIN_MAG2 0x0410//no +#define GC2083_AGAIN_MAG3 0x0411//no +#define GC2083_AGAIN_MAG4 0x0412 +#define GC2083_AGAIN_MAG5 0x0413 +#define GC2083_AGAIN_MAG6 0x0414 +#define GC2083_AGAIN_MAG7 0x0415 +#define GC2083_AGAIN_MAG8 0x0416 +#define GC2083_AGAIN_MAG9 0x0417 + +#define GC2083_DGAIN_H_ADDR 0x00b1 +#define GC2083_DGAIN_L_ADDR 0x00b2 +#define GC2083_VTS_H_ADDR 0x0d41 //(frame length) +#define GC2083_VTS_L_ADDR 0x0d42 + +#define GC2083_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); + GC2083_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC2083_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_astGc2083_mode[GC2083_MODE_1920X1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astGc2083_mode[GC2083_MODE_1920X1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 9474*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] : g_astGc2083_mode[GC2083_MODE_1920X1080P30].stExp[0].u16Def; + + pstAeSnsDft->u32MaxIntTime = g_astGc2083_mode[GC2083_MODE_1920X1080P30].stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = g_astGc2083_mode[GC2083_MODE_1920X1080P30].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); + GC2083_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astGc2083_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astGc2083_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astGc2083_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 > GC2083_FULL_LINES_MAX) ? GC2083_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; + + GC2083_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[29][13] = { + //0x00d0 0x0dc1 0x00b8 0x00b9 0x0155 0x0410 0x0411 0x0412 0x0413 0x0414 0x0415 0x0416 0x0417 + {0x00, 0x00, 0x01, 0x00, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x10, 0x00, 0x01, 0x0c, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x01, 0x00, 0x01, 0x1a, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x11, 0x00, 0x01, 0x2b, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x02, 0x00, 0x02, 0x00, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x12, 0x00, 0x02, 0x18, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x03, 0x00, 0x02, 0x33, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x13, 0x00, 0x03, 0x15, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x04, 0x00, 0x04, 0x00, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x14, 0x00, 0x04, 0xe0, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x05, 0x00, 0x05, 0x26, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x15, 0x00, 0x06, 0x2b, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x44, 0x00, 0x08, 0x00, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x54, 0x00, 0x09, 0x22, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x45, 0x00, 0x0b, 0x0d, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x55, 0x00, 0x0d, 0x16, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x04, 0x01, 0x10, 0x00, 0x19, 0x16, 0x16, 0x16, 0x16, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x14, 0x01, 0x13, 0x04, 0x19, 0x16, 0x16, 0x16, 0x16, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x24, 0x01, 0x16, 0x1a, 0x19, 0x16, 0x16, 0x16, 0x16, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x34, 0x01, 0x1a, 0x2b, 0x19, 0x16, 0x16, 0x16, 0x16, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x44, 0x01, 0x20, 0x00, 0x36, 0x18, 0x18, 0x18, 0x18, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x54, 0x01, 0x26, 0x07, 0x36, 0x18, 0x18, 0x18, 0x18, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x64, 0x01, 0x2c, 0x33, 0x36, 0x18, 0x18, 0x18, 0x18, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x74, 0x01, 0x35, 0x17, 0x36, 0x18, 0x18, 0x18, 0x18, 0x6f, 0x6f, 0x6f, 0x6f}, + {0x84, 0x01, 0x35, 0x17, 0x64, 0x16, 0x16, 0x16, 0x16, 0x72, 0x72, 0x72, 0x72}, + {0x94, 0x01, 0x35, 0x17, 0x64, 0x16, 0x16, 0x16, 0x16, 0x72, 0x72, 0x72, 0x72}, + {0x85, 0x01, 0x35, 0x17, 0x64, 0x16, 0x16, 0x16, 0x16, 0x72, 0x72, 0x72, 0x72}, + {0x95, 0x01, 0x35, 0x17, 0x64, 0x16, 0x16, 0x16, 0x16, 0x72, 0x72, 0x72, 0x72}, + {0xa5, 0x01, 0x35, 0x17, 0x64, 0x16, 0x16, 0x16, 0x16, 0x72, 0x72, 0x72, 0x72}, +}; + +static CVI_U32 gain_table[29] = { + 64, + 77, + 92, + 110, + 128, + 154, + 186, + 223, + 266, + 323, + 387, + 457, + 544, + 653, + 784, + 914, + 1078, + 1293, + 1541, + 1849, + 2177, + 2612, + 3136, + 3764, + 4504, + 5376, + 6656, + 7988, + 9474, +}; + +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] * 16)) { + *pu32AgainLin = *pu32AgainDb = gain_table[total - 1] * 16; + return CVI_SUCCESS; + } + + for (i = 1; i < total; i++) { + if (*pu32AgainLin < (gain_table[i] * 16)) + break; + } + i--; + // find the pregain + pregain = *pu32AgainLin * 64 / (gain_table[i] * 16); + // 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] * 16) / 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); + + GC2083_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 < (9474*16)) { + for (i = 1; i < total; i++) { + if (*pu32Again < (gain_table[i] * 16)) + break; + } + i--; + // find the pregain + u32Dgain = u32Again * 64 / (gain_table[i] * 16); + u32Again = i; + } else { + // find the pregain + u32Dgain = u32Again * 64 / (gain_table[total - 1] * 16); + u32Again = total - 1; + } + // u32Dgain = pu32Dgain[0] * 64 / 1024; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][0]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_HOLD].u32Data = 0X2e; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H].u32Data = regValTable[u32Again][1]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REL].u32Data = 0X28; + 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_AGAIN_MAG4].u32Data = regValTable[u32Again][7]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG5].u32Data = regValTable[u32Again][8]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG6].u32Data = regValTable[u32Again][9]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG7].u32Data = regValTable[u32Again][10]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG8].u32Data = regValTable[u32Again][11]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG9].u32Data = regValTable[u32Again][12]; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 6); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0x3F) << 2; + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "This Mode not support!\n"); + } + + 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 = CVI_NULL; + pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = CVI_NULL; + + 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 GC2083_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2083_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astGc2083_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; + + GC2083_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == GC2083_MODE_1920X1080P30_WDR) + pstSnsState->u8ImgMode = GC2083_MODE_1920X1080P30; + + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astGc2083_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); + GC2083_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_aunGc2083_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 = gc2083_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc2083_addr_byte; + pstI2c_data[i].u32DataByteNum = gc2083_data_byte; + } + + switch (pstSnsState->enWDRMode) { + default: + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC2083_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC2083_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = GC2083_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC2083_AGAIN_L_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC2083_COL_AGAIN_H_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC2083_COL_AGAIN_L_ADDR; + pstI2c_data[LINEAR_AGAIN_MAG1].u32RegAddr = GC2083_AGAIN_MAG1; + pstI2c_data[LINEAR_AGAIN_HOLD].u32RegAddr = GC2083_AGAIN_HOLD; + pstI2c_data[LINEAR_AGAIN_MAG2].u32RegAddr = GC2083_AGAIN_MAG2; + pstI2c_data[LINEAR_AGAIN_MAG3].u32RegAddr = GC2083_AGAIN_MAG3; + pstI2c_data[LINEAR_AGAIN_MAG4].u32RegAddr = GC2083_AGAIN_MAG4; + pstI2c_data[LINEAR_AGAIN_MAG5].u32RegAddr = GC2083_AGAIN_MAG5; + pstI2c_data[LINEAR_AGAIN_MAG6].u32RegAddr = GC2083_AGAIN_MAG6; + pstI2c_data[LINEAR_AGAIN_MAG7].u32RegAddr = GC2083_AGAIN_MAG7; + pstI2c_data[LINEAR_AGAIN_MAG8].u32RegAddr = GC2083_AGAIN_MAG8; + pstI2c_data[LINEAR_AGAIN_MAG9].u32RegAddr = GC2083_AGAIN_MAG9; + pstI2c_data[LINEAR_AGAIN_REL].u32RegAddr = GC2083_AGAIN_HOLD; + pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = GC2083_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = GC2083_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC2083_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC2083_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; + CVI_U32 vtsUpdate = 0; + CVI_U32 shutterUpdate = 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_L) && (i <= LINEAR_DGAIN_L)) + gainsUpdate = 1; + if ((i >= LINEAR_VTS_H) && (i <= LINEAR_VTS_L)) + vtsUpdate = 1; + if (i <= LINEAR_EXP_L) + shutterUpdate = 1; + + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + if (gainsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H].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_MAG5].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG6].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG7].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG8].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG9].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; + } + 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); + GC2083_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 (GC2083_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC2083_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; + + GC2083_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + /* Apply the setting on the fly */ + if (pstSnsState->bInit == CVI_TRUE && g_aeGc2083_MirrorFip[ViPipe] != eSnsMirrorFlip) { + gc2083_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeGc2083_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2083_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC2083_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astGc2083_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astGc2083_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astGc2083_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; + + GC2083_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc2083_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astGc2083_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astGc2083_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 = &gc2083_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 = gc2083_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc2083_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 (GC2083_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc2083_i2c_addr = s32I2cAddr; +} + +static CVI_S32 gc2083_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc2083_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2083_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)); + + GC2083_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2083_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC2083_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 = GC2083_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, GC2083_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, GC2083_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, GC2083_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_au16Gc2083_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc2083_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc2083_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc2083_standby, + .pfnRestart = gc2083_restart, + .pfnWriteReg = gc2083_write_register, + .pfnReadReg = gc2083_read_register, + .pfnSetBusInfo = gc2083_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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2083/gc2083_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2083/gc2083_cmos_ex.h new file mode 100644 index 00000000..1e2db118 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2083/gc2083_cmos_ex.h @@ -0,0 +1,99 @@ +#ifndef __GC2083_CMOS_EX_H_ +#define __GC2083_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 gc2083_linear_regs_e { + LINEAR_EXP_H = 0, //03 + LINEAR_EXP_L, //04 + LINEAR_AGAIN_L, //b3 + LINEAR_AGAIN_HOLD, //0x031d + LINEAR_AGAIN_H, + LINEAR_AGAIN_REL, //0x031d + LINEAR_COL_AGAIN_H, //b8 + LINEAR_COL_AGAIN_L, //b9 + LINEAR_AGAIN_MAG1, //0x155 + LINEAR_AGAIN_MAG2, //0xc2 + LINEAR_AGAIN_MAG3, //0xcf + LINEAR_AGAIN_MAG4, //0xd9 + LINEAR_AGAIN_MAG5, + LINEAR_AGAIN_MAG6, + LINEAR_AGAIN_MAG7, + LINEAR_AGAIN_MAG8, + LINEAR_AGAIN_MAG9, + LINEAR_DGAIN_H, //b1 + LINEAR_DGAIN_L, //b2 + LINEAR_VTS_H, //0x41 (frame length) + LINEAR_VTS_L, //0x42 + LINEAR_REGS_NUM +}; +typedef enum _GC2083_MODE_E { + GC2083_MODE_1920X1080P30 = 0, + GC2083_MODE_LINEAR_NUM, + GC2083_MODE_1920X1080P30_WDR = GC2083_MODE_LINEAR_NUM, + GC2083_MODE_NUM +} GC2083_MODE_E; + +typedef struct _GC2083_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC2083_STATE_S; + +typedef struct _GC2083_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]; +} GC2083_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc2083[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc2083_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2083_MirrorFip[VI_MAX_PIPE_NUM]; +extern CVI_U8 gc2083_i2c_addr; +extern const CVI_U32 gc2083_addr_byte; +extern const CVI_U32 gc2083_data_byte; +extern void gc2083_init(VI_PIPE ViPipe); +extern void gc2083_exit(VI_PIPE ViPipe); +extern void gc2083_standby(VI_PIPE ViPipe); +extern void gc2083_restart(VI_PIPE ViPipe); +extern int gc2083_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc2083_read_register(VI_PIPE ViPipe, int addr); +extern void gc2083_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int gc2083_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2083_CMOS_EX_H_ */ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2083/gc2083_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2083/gc2083_cmos_param.h new file mode 100644 index 00000000..2101cd5d --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2083/gc2083_cmos_param.h @@ -0,0 +1,222 @@ +#ifndef __GC2083_CMOS_PARAM_H_ +#define __GC2083_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 "gc2083_cmos_ex.h" + +static const GC2083_MODE_S g_astGc2083_mode[GC2083_MODE_NUM] = { + [GC2083_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 = 1125 - 8, + .u16Def = 400, + .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, + }, + }, +}; + +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 = {252, 252, 252, 252, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1092, 1092, 1092, 1092 +#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 + {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 gc2083_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 = {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 /* __GC2083_CMOS_PARAM_H_ */ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2083/gc2083_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2083/gc2083_sensor_ctl.c new file mode 100644 index 00000000..fbffb98e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2083/gc2083_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 "gc2083_cmos_ex.h" + +static void gc2083_linear_1080p30_init(VI_PIPE ViPipe); +static void gc2083_wdr_1080p30_init(VI_PIPE ViPipe); + +CVI_U8 gc2083_i2c_addr = 0x37;//0x6e +const CVI_U32 gc2083_addr_byte = 2; +const CVI_U32 gc2083_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc2083_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc2083_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, gc2083_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 gc2083_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 gc2083_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 (gc2083_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc2083_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, gc2083_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc2083_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 gc2083_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 (gc2083_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + if (gc2083_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc2083_addr_byte + gc2083_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + ret = read(g_fd[ViPipe], buf, gc2083_addr_byte + gc2083_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 gc2083_standby(VI_PIPE ViPipe) +{ + gc2083_write_register(ViPipe, 0x003e, 0x00); + gc2083_write_register(ViPipe, 0x03f7, 0x00); + gc2083_write_register(ViPipe, 0x03fc, 0x01); + gc2083_write_register(ViPipe, 0x03f9, 0x41); + + printf("%s...", __func__); +} + +void gc2083_restart(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastGc2083[ViPipe]->enWDRMode; + u8ImgMode = g_pastGc2083[ViPipe]->u8ImgMode; + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == GC2083_MODE_1920X1080P30_WDR) { + gc2083_write_register(ViPipe, 0x03f9, 0x40); + usleep(1); + gc2083_write_register(ViPipe, 0x03f7, 0x01); + gc2083_write_register(ViPipe, 0x03fc, 0x8e); + gc2083_write_register(ViPipe, 0x003e, 0x91); + } + } else { + gc2083_write_register(ViPipe, 0x03f9, 0x42); + usleep(1); + gc2083_write_register(ViPipe, 0x03f7, 0x11); + gc2083_write_register(ViPipe, 0x03fc, 0x8e); + gc2083_write_register(ViPipe, 0x003e, 0x91); + } + + printf("%s...", __func__); +} + +void gc2083_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc2083[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc2083_write_register(ViPipe, + g_pastGc2083[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc2083[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define GC2083_CHIP_ID_ADDR_H 0x03f0 +#define GC2083_CHIP_ID_ADDR_L 0x03f1 +#define GC2083_CHIP_ID 0x2083 + +void gc2083_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; + } + gc2083_write_register(ViPipe, 0x0015, value); + gc2083_write_register(ViPipe, 0x0d15, value); +} + +int gc2083_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc2083_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc2083_read_register(ViPipe, GC2083_CHIP_ID_ADDR_H); + nVal2 = gc2083_read_register(ViPipe, GC2083_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)) != GC2083_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc2083_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_U8 u8ImgMode; + + enWDRMode = g_pastGc2083[ViPipe]->enWDRMode; + u8ImgMode = g_pastGc2083[ViPipe]->u8ImgMode; + + gc2083_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_2To1_LINE) { + if (u8ImgMode == GC2083_MODE_1920X1080P30_WDR) { + gc2083_wdr_1080p30_init(ViPipe); + } + } else { + gc2083_linear_1080p30_init(ViPipe); + } + + + g_pastGc2083[ViPipe]->bInit = CVI_TRUE; +} + +void gc2083_exit(VI_PIPE ViPipe) +{ + gc2083_i2c_exit(ViPipe); +} + +static void gc2083_linear_1080p30_init(VI_PIPE ViPipe) +{ + delay_ms(10); + /****system****/ + gc2083_write_register(ViPipe, 0x03fe, 0xf0); + gc2083_write_register(ViPipe, 0x03fe, 0xf0); + gc2083_write_register(ViPipe, 0x03fe, 0xf0); + gc2083_write_register(ViPipe, 0x03fe, 0x00); + gc2083_write_register(ViPipe, 0x03f2, 0x00); + gc2083_write_register(ViPipe, 0x03f3, 0x00); + gc2083_write_register(ViPipe, 0x03f4, 0x36); + gc2083_write_register(ViPipe, 0x03f5, 0xc0); + gc2083_write_register(ViPipe, 0x03f6, 0x24); + gc2083_write_register(ViPipe, 0x03f7, 0x01); + gc2083_write_register(ViPipe, 0x03f8, 0x32); + gc2083_write_register(ViPipe, 0x03f9, 0x43); + gc2083_write_register(ViPipe, 0x03fc, 0x8e); + gc2083_write_register(ViPipe, 0x0381, 0x07); + gc2083_write_register(ViPipe, 0x00d7, 0x29); + gc2083_write_register(ViPipe, 0x0d6d, 0x18); + gc2083_write_register(ViPipe, 0x00d5, 0x03); + gc2083_write_register(ViPipe, 0x0082, 0x01); + gc2083_write_register(ViPipe, 0x0db3, 0xd4); + gc2083_write_register(ViPipe, 0x0db0, 0x0d); + gc2083_write_register(ViPipe, 0x0db5, 0x96); + gc2083_write_register(ViPipe, 0x0d05, 0x05); + gc2083_write_register(ViPipe, 0x0d06, 0xc9); + gc2083_write_register(ViPipe, 0x0d07, 0x00); + gc2083_write_register(ViPipe, 0x0d08, 0x11); + gc2083_write_register(ViPipe, 0x0d09, 0x00); + gc2083_write_register(ViPipe, 0x0d0a, 0x02); + gc2083_write_register(ViPipe, 0x000b, 0x00); + gc2083_write_register(ViPipe, 0x000c, 0x02); + gc2083_write_register(ViPipe, 0x0d0d, 0x04); + gc2083_write_register(ViPipe, 0x0d0e, 0x40); + gc2083_write_register(ViPipe, 0x000f, 0x07); + gc2083_write_register(ViPipe, 0x0010, 0x90); + gc2083_write_register(ViPipe, 0x0017, 0x0c); + gc2083_write_register(ViPipe, 0x0d73, 0x92); + gc2083_write_register(ViPipe, 0x0076, 0x00); + gc2083_write_register(ViPipe, 0x0d76, 0x00); + gc2083_write_register(ViPipe, 0x0d41, 0x04); + gc2083_write_register(ViPipe, 0x0d42, 0x65); + gc2083_write_register(ViPipe, 0x0d7a, 0x10); + gc2083_write_register(ViPipe, 0x0d19, 0x31); + gc2083_write_register(ViPipe, 0x0d25, 0xcb); + gc2083_write_register(ViPipe, 0x0d20, 0x60); + gc2083_write_register(ViPipe, 0x0d27, 0x03); + gc2083_write_register(ViPipe, 0x0d29, 0x60); + gc2083_write_register(ViPipe, 0x0d43, 0x10); + gc2083_write_register(ViPipe, 0x0d49, 0x10); + gc2083_write_register(ViPipe, 0x0d55, 0x18); + gc2083_write_register(ViPipe, 0x0dc2, 0x44); + gc2083_write_register(ViPipe, 0x0058, 0x3c); + gc2083_write_register(ViPipe, 0x00d8, 0x68); + gc2083_write_register(ViPipe, 0x00d9, 0x14); + gc2083_write_register(ViPipe, 0x00da, 0xc1); + gc2083_write_register(ViPipe, 0x0050, 0x18); + gc2083_write_register(ViPipe, 0x0db6, 0x3d); + gc2083_write_register(ViPipe, 0x00d2, 0xbc); + gc2083_write_register(ViPipe, 0x0d66, 0x42); + gc2083_write_register(ViPipe, 0x008c, 0x07); + gc2083_write_register(ViPipe, 0x008d, 0xff); + gc2083_write_register(ViPipe, 0x007a, 0x50); + gc2083_write_register(ViPipe, 0x00d0, 0x00); + gc2083_write_register(ViPipe, 0x0dc1, 0x00); + gc2083_write_register(ViPipe, 0x0102, 0xa9); + gc2083_write_register(ViPipe, 0x0158, 0x00); + gc2083_write_register(ViPipe, 0x0107, 0xa6); + gc2083_write_register(ViPipe, 0x0108, 0xa9); + gc2083_write_register(ViPipe, 0x0109, 0xa8); + gc2083_write_register(ViPipe, 0x010a, 0xa7); + gc2083_write_register(ViPipe, 0x010b, 0xff); + gc2083_write_register(ViPipe, 0x010c, 0xff); + gc2083_write_register(ViPipe, 0x0428, 0x86); + gc2083_write_register(ViPipe, 0x0429, 0x86); + gc2083_write_register(ViPipe, 0x042a, 0x86); + gc2083_write_register(ViPipe, 0x042b, 0x68); + gc2083_write_register(ViPipe, 0x042c, 0x68); + gc2083_write_register(ViPipe, 0x042d, 0x68); + gc2083_write_register(ViPipe, 0x042e, 0x68); + gc2083_write_register(ViPipe, 0x042f, 0x68); + gc2083_write_register(ViPipe, 0x0430, 0x4f); + gc2083_write_register(ViPipe, 0x0431, 0x68); + gc2083_write_register(ViPipe, 0x0432, 0x67); + gc2083_write_register(ViPipe, 0x0433, 0x66); + gc2083_write_register(ViPipe, 0x0434, 0x66); + gc2083_write_register(ViPipe, 0x0435, 0x66); + gc2083_write_register(ViPipe, 0x0436, 0x66); + gc2083_write_register(ViPipe, 0x0437, 0x66); + gc2083_write_register(ViPipe, 0x0438, 0x62); + gc2083_write_register(ViPipe, 0x0439, 0x62); + gc2083_write_register(ViPipe, 0x043a, 0x62); + gc2083_write_register(ViPipe, 0x043b, 0x62); + gc2083_write_register(ViPipe, 0x043c, 0x62); + gc2083_write_register(ViPipe, 0x043d, 0x62); + gc2083_write_register(ViPipe, 0x043e, 0x62); + gc2083_write_register(ViPipe, 0x043f, 0x62); + gc2083_write_register(ViPipe, 0x0077, 0x01); + gc2083_write_register(ViPipe, 0x0078, 0x65); + gc2083_write_register(ViPipe, 0x0079, 0x04); + gc2083_write_register(ViPipe, 0x0067, 0xa0); + gc2083_write_register(ViPipe, 0x0054, 0xff); + gc2083_write_register(ViPipe, 0x0055, 0x02); + gc2083_write_register(ViPipe, 0x0056, 0x00); + gc2083_write_register(ViPipe, 0x0057, 0x04); + gc2083_write_register(ViPipe, 0x005a, 0xff); + gc2083_write_register(ViPipe, 0x005b, 0x07); + gc2083_write_register(ViPipe, 0x0026, 0x01); + gc2083_write_register(ViPipe, 0x0152, 0x02); + gc2083_write_register(ViPipe, 0x0153, 0x50); + gc2083_write_register(ViPipe, 0x0155, 0x93); + gc2083_write_register(ViPipe, 0x0410, 0x16); + gc2083_write_register(ViPipe, 0x0411, 0x16); + gc2083_write_register(ViPipe, 0x0412, 0x16); + gc2083_write_register(ViPipe, 0x0413, 0x16); + gc2083_write_register(ViPipe, 0x0414, 0x6f); + gc2083_write_register(ViPipe, 0x0415, 0x6f); + gc2083_write_register(ViPipe, 0x0416, 0x6f); + gc2083_write_register(ViPipe, 0x0417, 0x6f); + gc2083_write_register(ViPipe, 0x04e0, 0x18); + gc2083_write_register(ViPipe, 0x0192, 0x04); + gc2083_write_register(ViPipe, 0x0194, 0x04); + gc2083_write_register(ViPipe, 0x0195, 0x04); + gc2083_write_register(ViPipe, 0x0196, 0x38); + gc2083_write_register(ViPipe, 0x0197, 0x07); + gc2083_write_register(ViPipe, 0x0198, 0x80); + gc2083_write_register(ViPipe, 0x0201, 0x27); + gc2083_write_register(ViPipe, 0x0202, 0x53); + gc2083_write_register(ViPipe, 0x0203, 0xce); + gc2083_write_register(ViPipe, 0x0204, 0x40); + gc2083_write_register(ViPipe, 0x0212, 0x07); + gc2083_write_register(ViPipe, 0x0213, 0x80); + gc2083_write_register(ViPipe, 0x0215, 0x12); + gc2083_write_register(ViPipe, 0x0229, 0x05); + gc2083_write_register(ViPipe, 0x0237, 0x03); + gc2083_write_register(ViPipe, 0x0d03, 0x00); + gc2083_write_register(ViPipe, 0x0d04, 0x04); + gc2083_write_register(ViPipe, 0x023e, 0x99); + + gc2083_default_reg_init(ViPipe); + delay_ms(80); + + printf("ViPipe:%d,===GC2083 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +static void gc2083_wdr_1080p30_init(VI_PIPE ViPipe) +{ + printf("ViPipe = %d\n", ViPipe); +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2093/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2093/Makefile new file mode 100644 index 00000000..a6b89d54 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2093/gc2093_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2093/gc2093_cmos.c new file mode 100644 index 00000000..60838823 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2093/gc2093_cmos.c @@ -0,0 +1,1214 @@ +#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 +#define GC2093_I2C_ADDR_1 0x7e +#define GC2093_I2C_ADDR_2 0x37 +#define GC2093_I2C_ADDR_IS_VALID(addr) ((addr) == GC2093_I2C_ADDR_1 || (addr) == GC2093_I2C_ADDR_2) + +/**************************************************************************** + * 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_1920X1080P60].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 if (pstSensorImageMode->f32Fps > 30) { + if (GC2093_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC2093_MODE_1920X1080P60; + 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 >= 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 = 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_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (GC2093_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc2093_i2c_addr = s32I2cAddr; +} + +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, + .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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2093/gc2093_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2093/gc2093_cmos_ex.h new file mode 100644 index 00000000..dd0e8d11 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2093/gc2093_cmos_ex.h @@ -0,0 +1,117 @@ +#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_1920X1080P60, + 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 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2093/gc2093_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2093/gc2093_cmos_param.h new file mode 100644 index 00000000..5b0afe2b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2093/gc2093_cmos_param.h @@ -0,0 +1,328 @@ +#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_1920X1080P60] = { + .name = "1920X1080P60", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 60, + .f32MinFps = 2.07, /* 1125 * 30 / 0x3FFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1250, + .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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2093/gc2093_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2093/gc2093_sensor_ctl.c new file mode 100644 index 00000000..a6142d01 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2093/gc2093_sensor_ctl.c @@ -0,0 +1,726 @@ +#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_linear_1080p60_init(VI_PIPE ViPipe); +static void gc2093_wdr_1080p30_init(VI_PIPE ViPipe); + +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 if (u8ImgMode == GC2093_MODE_1920X1080P30) { + gc2093_linear_1080p30_init(ViPipe); + } else { + gc2093_linear_1080p60_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_linear_1080p60_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 & 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, 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, 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, 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 & 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 60fps 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2145/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2145/Makefile new file mode 100644 index 00000000..ba45cb01 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2145/gc2145_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2145/gc2145_cmos.c new file mode 100644 index 00000000..d58dfdcb --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2145/gc2145_cmos.c @@ -0,0 +1,304 @@ +#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 >= VI_MAX_DEV_NUM) + 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2145/gc2145_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2145/gc2145_cmos_ex.h new file mode 100644 index 00000000..34bb36b2 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2145/gc2145_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2145/gc2145_cmos_param.h new file mode 100644 index 00000000..b1a2ee9a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2145/gc2145_cmos_param.h @@ -0,0 +1,71 @@ +#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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2145/gc2145_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc2145/gc2145_sensor_ctl.c new file mode 100644 index 00000000..20c98157 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4023/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4023/Makefile new file mode 100644 index 00000000..cd2e0182 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4023/gc4023_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4023/gc4023_cmos.c new file mode 100644 index 00000000..fbe45aea --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4023/gc4023_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4023/gc4023_cmos_ex.h new file mode 100644 index 00000000..924944c9 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4023/gc4023_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4023/gc4023_cmos_param.h new file mode 100644 index 00000000..a7de5679 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4023/gc4023_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4023/gc4023_sensor_ctl.c new file mode 100644 index 00000000..3e138368 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4653/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4653/Makefile new file mode 100644 index 00000000..553faf60 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4653/gc4653_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4653/gc4653_cmos.c new file mode 100644 index 00000000..4e698cc6 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4653/gc4653_cmos.c @@ -0,0 +1,1015 @@ +#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] = { + // for licheervnano + [0] = { .s8I2cDev = 4}, + [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) +#define GC4653_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); + 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); + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC4653_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + switch (u8Mode) { + case WDR_MODE_NONE: + // pstSnsState->u8ImgMode = GC4653_MODE_2560X1440P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astGc4653_mode[pstSnsState->u8ImgMode].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)); + + //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 if (pstSensorImageMode->f32Fps <= 60) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC4653_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC4653_MODE_1280X720P60; + else { + 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 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)); + if (pstSnsState->u8ImgMode == GC4653_MODE_1280X720P60) { + char *value = getenv("MAIX_SENSOR_FPS"); + if (value == NULL) { + pstRxAttr->mclk.freq = CAMPLL_FREQ_27M; + } else { + int fps = atoi(value); + if (fps == 80) { + pstRxAttr->mclk.freq = CAMPLL_FREQ_37P125M; + } else { + pstRxAttr->mclk.freq = CAMPLL_FREQ_27M; + } + } + } else if (pstSnsState->u8ImgMode == GC4653_MODE_2560X1440P30) { + pstRxAttr->mclk.freq = CAMPLL_FREQ_24M; + } + 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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4653/gc4653_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4653/gc4653_cmos_ex.h new file mode 100644 index 00000000..5a78ff18 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4653/gc4653_cmos_ex.h @@ -0,0 +1,94 @@ +#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_1280X720P60, + 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4653/gc4653_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4653/gc4653_cmos_param.h new file mode 100644 index 00000000..df2ecd95 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4653/gc4653_cmos_param.h @@ -0,0 +1,281 @@ +#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 = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 60, + + .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 = 1500, + .u32VtsDef = 750,//650 + .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, + }, + }, + [GC4653_MODE_1280X720P60] = { + .name = "1280X720P30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + .f32MaxFps = 60, + .f32MinFps = 2.75, /* 1500 * 30 / 16383 */ + .u32HtsDef = 1500, + .u32VtsDef = 750,//650 + .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, 0, -1, -1}, + .pn_swap = {0, 0, 0, 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4653/gc4653_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4653/gc4653_sensor_ctl.c new file mode 100644 index 00000000..1429f1a6 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/gcore_gc4653/gc4653_sensor_ctl.c @@ -0,0 +1,537 @@ +#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); +static void gc4653_linear_720p60_init(VI_PIPE ViPipe); + +CVI_U8 gc4653_i2c_addr = 0x29; +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) +{ + CVI_U8 u8ImgMode; + + gc4653_i2c_init(ViPipe); + + u8ImgMode = g_pastGc4653[ViPipe]->u8ImgMode; + + if (u8ImgMode == GC4653_MODE_1280X720P60) { + gc4653_linear_720p60_init(ViPipe); + } else { + 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) +{ + 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, 0x6c); + gc4653_write_register(ViPipe, 0x0327, 0x03); + gc4653_write_register(ViPipe, 0x0334, 0x40); + gc4653_write_register(ViPipe, 0x0336, 0x6c); + gc4653_write_register(ViPipe, 0x0337, 0x82); + gc4653_write_register(ViPipe, 0x0315, 0x25); + gc4653_write_register(ViPipe, 0x031c, 0xc6); + 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); + 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, 0x04); + gc4653_write_register(ViPipe, 0x0354, 0x07); + 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, 0x1e); + gc4653_write_register(ViPipe, 0x0515, 0x30); + gc4653_write_register(ViPipe, 0x02d9, 0x5c); + 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); + gc4653_write_register(ViPipe, 0x0202, 0x05); + gc4653_write_register(ViPipe, 0x0203, 0xd0); + gc4653_write_register(ViPipe, 0x0205, 0xc0); + gc4653_write_register(ViPipe, 0x02b0, 0x68); + gc4653_write_register(ViPipe, 0x0002, 0xa9); + gc4653_write_register(ViPipe, 0x0004, 0x01); + 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); + + gc4653_write_register(ViPipe, 0x0342, 0x06); + gc4653_write_register(ViPipe, 0x0343, 0x40); + 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, 0x10); //0x12 coninute mode, 0x10 no-continue mode + 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, 0x000f, 0x00); + gc4653_write_register(ViPipe, 0x0100, 0x09); //stream on + //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_write_register(ViPipe, 0x0000, 0x00); // end flag + + gc4653_default_reg_init(ViPipe); + delay_ms(10); + + printf("ViPipe:%d,===GC4653 1440P 30fps 10bit LINEAR Init OK!===\n", ViPipe); +} + +static void gc4653_linear_720p60_init(VI_PIPE ViPipe) +{ + 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, 0x0335, 0x55); + gc4653_write_register(ViPipe, 0x0315, 0x25); + gc4653_write_register(ViPipe, 0x031c, 0xc6); + 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); + gc4653_write_register(ViPipe, 0x0217, 0x40); + gc4653_write_register(ViPipe, 0x0234, 0x20); + gc4653_write_register(ViPipe, 0x0340, 0x05); + gc4653_write_register(ViPipe, 0x0341, 0xdd); + gc4653_write_register(ViPipe, 0x0341, 0xd0); + gc4653_write_register(ViPipe, 0x0345, 0x06); + gc4653_write_register(ViPipe, 0x034b, 0xb0); + + gc4653_write_register(ViPipe, 0x034c, 0x05); + gc4653_write_register(ViPipe, 0x034e, 0x02); + gc4653_write_register(ViPipe, 0x034f, 0xd0); + gc4653_write_register(ViPipe, 0x0352, 0x08); + gc4653_write_register(ViPipe, 0x0354, 0x08); + 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); + gc4653_write_register(ViPipe, 0x0202, 0x05); + gc4653_write_register(ViPipe, 0x0203, 0xd0); + gc4653_write_register(ViPipe, 0x0205, 0xc0); + gc4653_write_register(ViPipe, 0x02b0, 0x68); + gc4653_write_register(ViPipe, 0x0002, 0xa9); + gc4653_write_register(ViPipe, 0x0004, 0x01); + 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); + gc4653_write_register(ViPipe, 0x0342, 0x06); + gc4653_write_register(ViPipe, 0x0343, 0x40); + 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); + + gc4653_write_register(ViPipe, 0x000f, 0x00); + // 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_write_register(ViPipe, 0x0000, 0x00); // end flag + + gc4653_default_reg_init(ViPipe); + delay_ms(10); + + printf("ViPipe:%d,===GC4653 720P 60fps 10bit LINEAR Init OK!===\n", ViPipe); +} \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008/Makefile new file mode 100644 index 00000000..f0e1a474 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008/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_mis2008.a +TARGET_SO = $(MW_LIB)/libsns_mis2008.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008/mis2008_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008/mis2008_cmos.c new file mode 100644 index 00000000..1cec562b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008/mis2008_cmos.c @@ -0,0 +1,1042 @@ +#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 "mis2008_cmos_ex.h" +#include "mis2008_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 MIS2008_ID 2008 +#define SENSOR_MIS2008_WIDTH 1920 +#define SENSOR_MIS2008_HEIGHT 1080 +#define MIS2008_I2C_ADDR_1 0x30 +#define MIS2008_I2C_ADDR_2 0x32 +#define MIS2008_I2C_ADDR_IS_VALID(addr) ((addr) == MIS2008_I2C_ADDR_1 || (addr) == MIS2008_I2C_ADDR_2) + +#define MIS2008_EXPACCURACY (1) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastMIS2008[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define MIS2008_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastMIS2008[dev]) +#define MIS2008_SENSOR_SET_CTX(dev, pstCtx) (g_pastMIS2008[dev] = pstCtx) +#define MIS2008_SENSOR_RESET_CTX(dev) (g_pastMIS2008[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunMIS2008_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16MIS2008_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16MIS2008_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeMis2008_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); +/*****MIS2008 Lines Range*****/ +#define MIS2008_FULL_LINES_MAX (0xFFFF) + +/*****MIS2008 Register Address*****/ +#define MIS2008_EXP_ADDR 0x3100 +#define MIS2008_AGAIN_ADDR 0x3102 +#define MIS2008_DGAIN_ADDR 0x3700 +#define MIS2008_VMAX_ADDR 0x3200 +#define MIS2008_FLIP_MIRROR_ADDR 0x3007 + +#define MIS2008_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); + MIS2008_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = MIS2008_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = MIS2008_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_astMIS2008_mode[pstSnsState->u8ImgMode].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astMIS2008_mode[pstSnsState->u8ImgMode].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = g_astMIS2008_mode[pstSnsState->u8ImgMode].stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = g_astMIS2008_mode[pstSnsState->u8ImgMode].stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = g_astMIS2008_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = g_astMIS2008_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_astMIS2008_mode[pstSnsState->u8ImgMode].stExp[0].u32Max; + pstAeSnsDft->u32MinIntTime = g_astMIS2008_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); + MIS2008_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astMIS2008_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astMIS2008_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astMIS2008_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case MIS2008_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 > MIS2008_FULL_LINES_MAX) ? MIS2008_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; + //frame high addr + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_ADDR].u32Data = ((u32VMAX & 0xFF00)>>8);//data[15:8] => [7:0] //h + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF);//data[7:0] [7:0] //l + + 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; + + MIS2008_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* 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_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xFF00) >> 8); //data[15:8] => [7:0] //h + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0xFF)); //data[7:0] [7:0] //l + + 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 = 1984, + .idxBase = 0, + .regGain = 0x01, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 3008, + .idxBase = 16, + .regGain = 0x02, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x03, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 5056, + .idxBase = 48, + .regGain = 0x04, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 6080, + .idxBase = 64, + .regGain = 0x05, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 7104, + .idxBase = 80, + .regGain = 0x06, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 8128, + .idxBase = 96, + .regGain = 0x07, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 9152, + .idxBase = 112, + .regGain = 0x08, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 10176, + .idxBase = 128, + .regGain = 0x09, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 11200, + .idxBase = 144, + .regGain = 0x0a, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 12224, + .idxBase = 160, + .regGain = 0x0b, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 13248, + .idxBase = 176, + .regGain = 0x0c, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 14272, + .idxBase = 192, + .regGain = 0x0d, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 15296, + .idxBase = 208, + .regGain = 0x0e, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 16320, + .idxBase = 224, + .regGain = 0x0f, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, +}; + +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 CVI_U32 Again_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, 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 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; + + MIS2008_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]; + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_ADDR].u32Data = (u32Again & 0x7F); + + /* 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 & 0x0e)>>1); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_D_FINEGAIN_ADDR].u32Data =((info->regGain & 0x01)<<7) | ((u32Dgain & 0x0F)<<3); + 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 MIS2008_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + MIS2008_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astMIS2008_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; + + MIS2008_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = MIS2008_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astMIS2008_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); + MIS2008_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_aunMIS2008_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 = mis2008_i2c_addr; + pstI2c_data[i].u32AddrByteNum = mis2008_addr_byte; + pstI2c_data[i].u32DataByteNum = mis2008_data_byte; + } + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = MIS2008_EXP_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = MIS2008_EXP_ADDR + 1; + + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = MIS2008_AGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_ADDR].u32RegAddr = MIS2008_DGAIN_ADDR; + pstI2c_data[LINEAR_D_FINEGAIN_ADDR].u32RegAddr = MIS2008_DGAIN_ADDR + 1; + + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = MIS2008_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = MIS2008_VMAX_ADDR + 1; + pstI2c_data[LINEAR_FLIP_MIRROR_ADDR].u32RegAddr = MIS2008_FLIP_MIRROR_ADDR; + 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]; + pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR_ADDR].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); + MIS2008_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 (MIS2008_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = MIS2008_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_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; + ISP_SNS_ISP_INFO_S *pstIspCfg0 = CVI_NULL; + CVI_U8 value = 0; + CVI_U8 start_x, start_y; + + MIS2008_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + pstIspCfg0 = &pstSnsState->astSyncInfo[0].ispCfg; + + if (pstSnsState->bInit == CVI_TRUE && g_aeMis2008_MirrorFip[ViPipe] != eSnsMirrorFlip) { + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + value |= 0; + start_x = 4; + start_y = 4; + break; + case ISP_SNS_MIRROR: + value |= 0x01; + start_x = 5; + start_y = 4; + break; + case ISP_SNS_FLIP: + value |= 0x02; + start_x = 4; + start_y = 5; + break; + case ISP_SNS_MIRROR_FLIP: + value |= 0x03; + start_x = 5; + start_y = 5; + break; + default: + return; + } + + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR_ADDR].u32Data = value; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR_ADDR].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR_ADDR].u8DropFrmNum = 1; + pstIspCfg0->img_size[0].stWndRect.s32X = start_x; + pstIspCfg0->img_size[0].stWndRect.s32Y = start_y; + g_aeMis2008_MirrorFip[ViPipe] = eSnsMirrorFlip; + } + +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const MIS2008_MODE_S *pstMode = CVI_NULL; + + MIS2008_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = MIS2008_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astMIS2008_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; + + MIS2008_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &mis2008_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astMIS2008_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astMIS2008_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 = &mis2008_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 = mis2008_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = mis2008_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 (MIS2008_I2C_ADDR_IS_VALID(s32I2cAddr)) + mis2008_i2c_addr = s32I2cAddr; +} + +static CVI_S32 mis2008_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunMIS2008_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + MIS2008_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)); + + MIS2008_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + MIS2008_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + MIS2008_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 = MIS2008_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, MIS2008_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, MIS2008_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, MIS2008_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_au16MIS2008_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16MIS2008_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsMIS2008_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = mis2008_standby, + .pfnRestart = mis2008_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = mis2008_write_register, + .pfnReadReg = mis2008_read_register, + .pfnSetBusInfo = mis2008_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 = mis2008_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008/mis2008_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008/mis2008_cmos_ex.h new file mode 100644 index 00000000..a758d273 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008/mis2008_cmos_ex.h @@ -0,0 +1,79 @@ +#ifndef __MIS2008_CMOS_EX_H_ +#define __MIS2008_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 mis2008_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_FLIP_MIRROR_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _MIS2008_MODE_E { + MIS2008_MODE_1080P30 = 0, + MIS2008_MODE_NUM +} MIS2008_MODE_E; + +typedef struct _MIS2008_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]; +} MIS2008_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastMIS2008[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunMIS2008_BusInfo[]; +extern CVI_U16 g_au16MIS2008_GainMode[]; +extern CVI_U16 g_au16MIS2008_L2SMode[]; +extern CVI_U8 mis2008_i2c_addr; +extern const CVI_U32 mis2008_addr_byte; +extern const CVI_U32 mis2008_data_byte; +extern void mis2008_init(VI_PIPE ViPipe); +extern void mis2008_exit(VI_PIPE ViPipe); +extern void mis2008_standby(VI_PIPE ViPipe); +extern void mis2008_restart(VI_PIPE ViPipe); +extern int mis2008_write_register(VI_PIPE ViPipe, int addr, int data); +extern int mis2008_read_register(VI_PIPE ViPipe, int addr); +extern void mis2008_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int mis2008_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __MIS2008_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008/mis2008_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008/mis2008_cmos_param.h new file mode 100644 index 00000000..1de9a7f9 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008/mis2008_cmos_param.h @@ -0,0 +1,126 @@ +#ifndef __MIS2008_CMOS_PARAM_H_ +#define __MIS2008_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 "mis2008_cmos_ex.h" + +static const MIS2008_MODE_S g_astMIS2008_mode[MIS2008_MODE_NUM] = { + [MIS2008_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1928, + .u32Height = 1088, + }, + .stWndRect = { + .s32X = 8, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1928, + .u32Height = 1088, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1, /* 1500 * 30 / 0x7FFF*/ + .u32HtsDef = 2200, + .u32VtsDef = 1125, + .stExp[0] = {//exp_time + .u32Min = 1, + .u32Max = 1125 - 1, //exp_max + .u32Def = 128, + .u32Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 16128, + .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 = {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 mis2008_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}, + .pn_swap = {1, 1, 1, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 8, + }, + }, + .mclk = { + .cam = 1, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __MIS2008_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008/mis2008_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008/mis2008_sensor_ctl.c new file mode 100644 index 00000000..4f2523af --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008/mis2008_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 "mis2008_cmos_ex.h" + +static void mis2008_linear_1080p30_init(VI_PIPE ViPipe); + +CVI_U8 mis2008_i2c_addr = 0x30; /* I2C Address of MIS2008 */ +const CVI_U32 mis2008_addr_byte = 2; +const CVI_U32 mis2008_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int mis2008_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunMIS2008_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, mis2008_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 mis2008_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 mis2008_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 (mis2008_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, mis2008_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, mis2008_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (mis2008_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 mis2008_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 (mis2008_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (mis2008_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, mis2008_addr_byte + mis2008_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 mis2008_standby(VI_PIPE ViPipe) +{ + mis2008_write_register(ViPipe, 0x3006, 0x02); +} + +void mis2008_restart(VI_PIPE ViPipe) +{ + mis2008_write_register(ViPipe, 0x3006, 0x01); +} + +void mis2008_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastMIS2008[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + mis2008_write_register(ViPipe, + g_pastMIS2008[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastMIS2008[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define MIS2008_CHIP_ID_HI_ADDR 0x3000 +#define MIS2008_CHIP_ID_LO_ADDR 0x3001 +#define MIS2008_CHIP_ID 0x2008 + +int mis2008_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + if (mis2008_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + delay_ms(5); + + nVal = mis2008_read_register(ViPipe, MIS2008_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 = mis2008_read_register(ViPipe, MIS2008_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 != MIS2008_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void mis2008_init(VI_PIPE ViPipe) +{ + mis2008_i2c_init(ViPipe); + + mis2008_linear_1080p30_init(ViPipe); + + g_pastMIS2008[ViPipe]->bInit = CVI_TRUE; +} + +void mis2008_exit(VI_PIPE ViPipe) +{ + mis2008_i2c_exit(ViPipe); +} + +/* 1080p30 */ +static void mis2008_linear_1080p30_init(VI_PIPE ViPipe) +{ + /* [ParaList] */ + mis2008_write_register(ViPipe, 0x300a ,0x01); + mis2008_write_register(ViPipe, 0x3006 ,0x02); + mis2008_write_register(ViPipe, 0x3201 ,0x65); + mis2008_write_register(ViPipe, 0x3200 ,0x04); + mis2008_write_register(ViPipe, 0x3203 ,0x98); + mis2008_write_register(ViPipe, 0x3202 ,0x08); + + mis2008_write_register(ViPipe, 0x3205 ,0x04); + mis2008_write_register(ViPipe, 0x3204 ,0x00); + mis2008_write_register(ViPipe, 0x3207 ,0x43); + mis2008_write_register(ViPipe, 0x3206 ,0x04); + + mis2008_write_register(ViPipe, 0x3209 ,0x04); + mis2008_write_register(ViPipe, 0x3208 ,0x00); + mis2008_write_register(ViPipe, 0x320b ,0x8b); + mis2008_write_register(ViPipe, 0x320a ,0x07); + + //mis2008_write_register(ViPipe, 0x3007 ,0x00); + mis2008_write_register(ViPipe, 0x3007 ,0x00); + mis2008_write_register(ViPipe, 0x3300 ,0x21); + mis2008_write_register(ViPipe, 0x3301 ,0x00); + mis2008_write_register(ViPipe, 0x3302 ,0x02); + mis2008_write_register(ViPipe, 0x3303 ,0x06); + mis2008_write_register(ViPipe, 0x330d ,0x00); + mis2008_write_register(ViPipe, 0x330b ,0x01); + mis2008_write_register(ViPipe, 0x330f ,0x0f); + mis2008_write_register(ViPipe, 0x3013 ,0x00); + mis2008_write_register(ViPipe, 0x3637 ,0x1e); + mis2008_write_register(ViPipe, 0x3900 ,0x07); + mis2008_write_register(ViPipe, 0x2107 ,0x00); + mis2008_write_register(ViPipe, 0x330e ,0x00); + + mis2008_write_register(ViPipe, 0x3900 ,0x07); + mis2008_write_register(ViPipe, 0x2108 ,0x01); + mis2008_write_register(ViPipe, 0x3c40 ,0x8c); + mis2008_write_register(ViPipe, 0x3b01 ,0x3f); + mis2008_write_register(ViPipe, 0x3b03 ,0x3f); + mis2008_write_register(ViPipe, 0x3902 ,0x01); + mis2008_write_register(ViPipe, 0x3904 ,0x00); + mis2008_write_register(ViPipe, 0x3903 ,0x00); + mis2008_write_register(ViPipe, 0x3906 ,0x1e); + mis2008_write_register(ViPipe, 0x3905 ,0x00); + mis2008_write_register(ViPipe, 0x3908 ,0x71); + mis2008_write_register(ViPipe, 0x3907 ,0x10); + mis2008_write_register(ViPipe, 0x390a ,0xff); + mis2008_write_register(ViPipe, 0x3909 ,0x1f); + mis2008_write_register(ViPipe, 0x390c ,0x67); + mis2008_write_register(ViPipe, 0x390b ,0x03); + mis2008_write_register(ViPipe, 0x390e ,0x77); + mis2008_write_register(ViPipe, 0x390d ,0x00); + mis2008_write_register(ViPipe, 0x3910 ,0x71); + mis2008_write_register(ViPipe, 0x390f ,0x10); + mis2008_write_register(ViPipe, 0x3912 ,0xff); + mis2008_write_register(ViPipe, 0x3911 ,0x1f); + mis2008_write_register(ViPipe, 0x3919 ,0x00); + mis2008_write_register(ViPipe, 0x3918 ,0x00); + mis2008_write_register(ViPipe, 0x391b ,0x91); + mis2008_write_register(ViPipe, 0x391a ,0x01); + mis2008_write_register(ViPipe, 0x3983 ,0x5a); + mis2008_write_register(ViPipe, 0x3982 ,0x00); + mis2008_write_register(ViPipe, 0x3985 ,0x0f); + mis2008_write_register(ViPipe, 0x3984 ,0x00); + mis2008_write_register(ViPipe, 0x391d ,0x00); + mis2008_write_register(ViPipe, 0x391c ,0x00); + mis2008_write_register(ViPipe, 0x391f ,0x65); + mis2008_write_register(ViPipe, 0x391e ,0x10); + mis2008_write_register(ViPipe, 0x3921 ,0xff); + mis2008_write_register(ViPipe, 0x3920 ,0x1f); + mis2008_write_register(ViPipe, 0x3923 ,0xff); + mis2008_write_register(ViPipe, 0x3922 ,0x1f); + mis2008_write_register(ViPipe, 0x3932 ,0x00); + mis2008_write_register(ViPipe, 0x3931 ,0x00); + mis2008_write_register(ViPipe, 0x3934 ,0x65); + mis2008_write_register(ViPipe, 0x3933 ,0x01); + mis2008_write_register(ViPipe, 0x393f ,0x6c); + mis2008_write_register(ViPipe, 0x393e ,0x00); + mis2008_write_register(ViPipe, 0x3941 ,0x67); + mis2008_write_register(ViPipe, 0x3940 ,0x00); + mis2008_write_register(ViPipe, 0x3943 ,0x55); + mis2008_write_register(ViPipe, 0x3942 ,0x01); + mis2008_write_register(ViPipe, 0x3945 ,0xc2); + mis2008_write_register(ViPipe, 0x3944 ,0x02); + mis2008_write_register(ViPipe, 0x3925 ,0x95); + mis2008_write_register(ViPipe, 0x3924 ,0x00); + mis2008_write_register(ViPipe, 0x3927 ,0xe1); + mis2008_write_register(ViPipe, 0x3926 ,0x02); + mis2008_write_register(ViPipe, 0x3947 ,0x74); + mis2008_write_register(ViPipe, 0x3946 ,0x01); + mis2008_write_register(ViPipe, 0x3949 ,0xda); + mis2008_write_register(ViPipe, 0x3948 ,0x0e); + mis2008_write_register(ViPipe, 0x394b ,0x42); + mis2008_write_register(ViPipe, 0x394a ,0x03); + mis2008_write_register(ViPipe, 0x394d ,0xf2); + mis2008_write_register(ViPipe, 0x394c ,0x01); + mis2008_write_register(ViPipe, 0x3913 ,0x01); + mis2008_write_register(ViPipe, 0x3915 ,0x0f); + mis2008_write_register(ViPipe, 0x3914 ,0x00); + mis2008_write_register(ViPipe, 0x3917 ,0x67); + mis2008_write_register(ViPipe, 0x3916 ,0x03); + mis2008_write_register(ViPipe, 0x392a ,0x1e); + mis2008_write_register(ViPipe, 0x3929 ,0x00); + mis2008_write_register(ViPipe, 0x392c ,0x0f); + mis2008_write_register(ViPipe, 0x392b ,0x00); + mis2008_write_register(ViPipe, 0x392e ,0x0f); + mis2008_write_register(ViPipe, 0x392d ,0x00); + mis2008_write_register(ViPipe, 0x3930 ,0x6e); + mis2008_write_register(ViPipe, 0x392f ,0x03); + mis2008_write_register(ViPipe, 0x397f ,0x00); + mis2008_write_register(ViPipe, 0x397e ,0x00); + mis2008_write_register(ViPipe, 0x3981 ,0x77); + mis2008_write_register(ViPipe, 0x3980 ,0x00); + mis2008_write_register(ViPipe, 0x395d ,0x80); + mis2008_write_register(ViPipe, 0x395c ,0x10); + mis2008_write_register(ViPipe, 0x3962 ,0x9e); + mis2008_write_register(ViPipe, 0x3961 ,0x10); + mis2008_write_register(ViPipe, 0x3977 ,0x22); + mis2008_write_register(ViPipe, 0x3976 ,0x00); + mis2008_write_register(ViPipe, 0x3978 ,0x00); + mis2008_write_register(ViPipe, 0x3979 ,0x04); + mis2008_write_register(ViPipe, 0x396d ,0xc2); + mis2008_write_register(ViPipe, 0x396c ,0x02); + mis2008_write_register(ViPipe, 0x396f ,0xc2); + mis2008_write_register(ViPipe, 0x396e ,0x02); + mis2008_write_register(ViPipe, 0x3971 ,0xc2); + mis2008_write_register(ViPipe, 0x3970 ,0x02); + mis2008_write_register(ViPipe, 0x3973 ,0xc2); + mis2008_write_register(ViPipe, 0x3972 ,0x02); + + mis2008_write_register(ViPipe, 0x3900 ,0x01); + mis2008_write_register(ViPipe, 0x3600 ,0x00); + mis2008_write_register(ViPipe, 0x3707 ,0x00); + mis2008_write_register(ViPipe, 0x3708 ,0x80); + mis2008_write_register(ViPipe, 0x3709 ,0x00); + mis2008_write_register(ViPipe, 0x370a ,0x80); + mis2008_write_register(ViPipe, 0x370b ,0x00); + mis2008_write_register(ViPipe, 0x370c ,0x80); + mis2008_write_register(ViPipe, 0x370d ,0x00); + mis2008_write_register(ViPipe, 0x370e ,0x80); + mis2008_write_register(ViPipe, 0x3006 ,0x00); + + + mis2008_write_register(ViPipe, 0x3012 ,0x01); + mis2008_write_register(ViPipe, 0x3600 ,0x13); + mis2008_write_register(ViPipe, 0x3601 ,0x02); + mis2008_write_register(ViPipe, 0x360e ,0x00); + mis2008_write_register(ViPipe, 0x360f ,0x00); + mis2008_write_register(ViPipe, 0x3610 ,0x02); + mis2008_write_register(ViPipe, 0x3707 ,0x00); + mis2008_write_register(ViPipe, 0x3708 ,0x40); + mis2008_write_register(ViPipe, 0x3709 ,0x00); + mis2008_write_register(ViPipe, 0x370a ,0x40); + mis2008_write_register(ViPipe, 0x370b ,0x00); + mis2008_write_register(ViPipe, 0x370c ,0x40); + mis2008_write_register(ViPipe, 0x370d ,0x00); + mis2008_write_register(ViPipe, 0x370e ,0x40); + mis2008_write_register(ViPipe, 0x3800 ,0x01); + mis2008_write_register(ViPipe, 0x3a03 ,0x03); + mis2008_write_register(ViPipe, 0x3a02 ,0x0b); + mis2008_write_register(ViPipe, 0x3a08 ,0x34); + mis2008_write_register(ViPipe, 0x3a1b ,0x54); + mis2008_write_register(ViPipe, 0x3a1e ,0x80); + mis2008_write_register(ViPipe, 0x3100 ,0x04); + mis2008_write_register(ViPipe, 0x3101 ,0x64); + mis2008_write_register(ViPipe, 0x3a1c ,0x10); + mis2008_write_register(ViPipe, 0x3a0C ,0x04); + mis2008_write_register(ViPipe, 0x3a0D ,0x12); + mis2008_write_register(ViPipe, 0x3a0E ,0x15); + mis2008_write_register(ViPipe, 0x3a0F ,0x18); + mis2008_write_register(ViPipe, 0x3a10 ,0x20); + mis2008_write_register(ViPipe, 0x3a11 ,0x3c); + + mis2008_default_reg_init(ViPipe); + + + delay_ms(100); + + printf("ViPipe:%d,===MIS2008 1080P 30fps 12bit LINE Init OK!===\n", ViPipe); +} + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008_1L/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008_1L/Makefile new file mode 100644 index 00000000..65a27b34 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008_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_mis2008_1l.a +TARGET_SO = $(MW_LIB)/libsns_mis2008_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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008_1L/mis2008_1l_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008_1L/mis2008_1l_cmos.c new file mode 100644 index 00000000..f097d416 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008_1L/mis2008_1l_cmos.c @@ -0,0 +1,1044 @@ +#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 "mis2008_1l_cmos_ex.h" +#include "mis2008_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 MIS2008_1L_ID 2008 +#define SENSOR_MIS2008_1L_WIDTH 1920 +#define SENSOR_MIS2008_1L_HEIGHT 1080 +#define MIS2008_1L_I2C_ADDR_1 0x30 +#define MIS2008_1L_I2C_ADDR_2 0x32 +#define MIS2008_1L_I2C_ADDR_IS_VALID(addr) ((addr) == MIS2008_1L_I2C_ADDR_1 || (addr) == MIS2008_1L_I2C_ADDR_2) + +#define MIS2008_1L_EXPACCURACY (1) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastMIS2008_1L[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define MIS2008_1L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastMIS2008_1L[dev]) +#define MIS2008_1L_SENSOR_SET_CTX(dev, pstCtx) (g_pastMIS2008_1L[dev] = pstCtx) +#define MIS2008_1L_SENSOR_RESET_CTX(dev) (g_pastMIS2008_1L[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunMIS2008_1L_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16MIS2008_1L_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16MIS2008_1L_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeMis2008_1l_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); +/*****MIS2008_1L Lines Range*****/ +#define MIS2008_1L_FULL_LINES_MAX (0xFFFF) + +/*****MIS2008_1L Register Address*****/ +#define MIS2008_1L_EXP_ADDR 0x3100 +#define MIS2008_1L_AGAIN_ADDR 0x3102 +#define MIS2008_1L_DGAIN_ADDR 0x3700 +#define MIS2008_1L_VMAX_ADDR 0x3200 +#define MIS2008_1L_FLIP_MIRROR_ADDR 0x3007 + +#define MIS2008_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) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + MIS2008_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = MIS2008_1L_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = MIS2008_1L_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_astMIS2008_1L_mode[pstSnsState->u8ImgMode].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astMIS2008_1L_mode[pstSnsState->u8ImgMode].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = g_astMIS2008_1L_mode[pstSnsState->u8ImgMode].stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = g_astMIS2008_1L_mode[pstSnsState->u8ImgMode].stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = g_astMIS2008_1L_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = g_astMIS2008_1L_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_astMIS2008_1L_mode[pstSnsState->u8ImgMode].stExp[0].u32Max; + pstAeSnsDft->u32MinIntTime = g_astMIS2008_1L_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); + MIS2008_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astMIS2008_1L_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astMIS2008_1L_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astMIS2008_1L_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case MIS2008_1L_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 > MIS2008_1L_FULL_LINES_MAX) ? MIS2008_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; + //frame high addr + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_ADDR].u32Data = ((u32VMAX & 0xFF00)>>8);//data[15:8] => [7:0] //h + pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF);//data[7:0] [7:0] //l + + 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; + + MIS2008_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* 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_SHS1_0_ADDR].u32Data = + ((u32TmpIntTime & 0xFF00) >> 8); //data[15:8] => [7:0] //h + pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0xFF)); //data[7:0] [7:0] //l + + 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 = 1984, + .idxBase = 0, + .regGain = 0x01, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 3008, + .idxBase = 16, + .regGain = 0x02, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x03, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 5056, + .idxBase = 48, + .regGain = 0x04, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 6080, + .idxBase = 64, + .regGain = 0x05, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 7104, + .idxBase = 80, + .regGain = 0x06, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 8128, + .idxBase = 96, + .regGain = 0x07, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 9152, + .idxBase = 112, + .regGain = 0x08, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 10176, + .idxBase = 128, + .regGain = 0x09, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 11200, + .idxBase = 144, + .regGain = 0x0a, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 12224, + .idxBase = 160, + .regGain = 0x0b, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 13248, + .idxBase = 176, + .regGain = 0x0c, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 14272, + .idxBase = 192, + .regGain = 0x0d, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 15296, + .idxBase = 208, + .regGain = 0x0e, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 16320, + .idxBase = 224, + .regGain = 0x0f, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, +}; + +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 CVI_U32 Again_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, 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 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; + + MIS2008_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]; + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_ADDR].u32Data = (u32Again & 0x7F); + + /* 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 & 0x0e)>>1); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_D_FINEGAIN_ADDR].u32Data = + ((info->regGain & 0x01)<<7) | ((u32Dgain & 0x0F)<<3); + 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 MIS2008_1L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + MIS2008_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astMIS2008_1L_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; + + MIS2008_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = MIS2008_1L_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astMIS2008_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); + MIS2008_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_aunMIS2008_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 = mis2008_1l_i2c_addr; + pstI2c_data[i].u32AddrByteNum = mis2008_1l_addr_byte; + pstI2c_data[i].u32DataByteNum = mis2008_1l_data_byte; + } + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = MIS2008_1L_EXP_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = MIS2008_1L_EXP_ADDR + 1; + + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = MIS2008_1L_AGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_ADDR].u32RegAddr = MIS2008_1L_DGAIN_ADDR; + pstI2c_data[LINEAR_D_FINEGAIN_ADDR].u32RegAddr = MIS2008_1L_DGAIN_ADDR + 1; + + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = MIS2008_1L_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = MIS2008_1L_VMAX_ADDR + 1; + pstI2c_data[LINEAR_FLIP_MIRROR_ADDR].u32RegAddr = MIS2008_1L_FLIP_MIRROR_ADDR; + 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]; + pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR_ADDR].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); + MIS2008_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 (MIS2008_1L_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = MIS2008_1L_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_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; + ISP_SNS_ISP_INFO_S *pstIspCfg0 = CVI_NULL; + CVI_U8 value = 0; + CVI_U8 start_x, start_y; + + MIS2008_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + pstIspCfg0 = &pstSnsState->astSyncInfo[0].ispCfg; + + if (pstSnsState->bInit == CVI_TRUE && g_aeMis2008_1l_MirrorFip[ViPipe] != eSnsMirrorFlip) { + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + value |= 0; + start_x = 4; + start_y = 4; + break; + case ISP_SNS_MIRROR: + value |= 0x01; + start_x = 5; + start_y = 4; + break; + case ISP_SNS_FLIP: + value |= 0x02; + start_x = 4; + start_y = 5; + break; + case ISP_SNS_MIRROR_FLIP: + value |= 0x03; + start_x = 5; + start_y = 5; + break; + default: + return; + } + + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR_ADDR].u32Data = value; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR_ADDR].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR_ADDR].u8DropFrmNum = 1; + pstIspCfg0->img_size[0].stWndRect.s32X = start_x; + pstIspCfg0->img_size[0].stWndRect.s32Y = start_y; + g_aeMis2008_1l_MirrorFip[ViPipe] = eSnsMirrorFlip; + } + +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const MIS2008_1L_MODE_S *pstMode = CVI_NULL; + + MIS2008_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = MIS2008_1L_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astMIS2008_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; + + MIS2008_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &mis2008_1l_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astMIS2008_1L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astMIS2008_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 = &mis2008_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 = mis2008_1l_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = mis2008_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 (MIS2008_1L_I2C_ADDR_IS_VALID(s32I2cAddr)) + mis2008_1l_i2c_addr = s32I2cAddr; +} + +static CVI_S32 mis2008_1l_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunMIS2008_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; + + MIS2008_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)); + + MIS2008_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; + + MIS2008_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + MIS2008_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 = MIS2008_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, MIS2008_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, MIS2008_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, MIS2008_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_au16MIS2008_1L_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16MIS2008_1L_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsMIS2008_1L_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = mis2008_1l_standby, + .pfnRestart = mis2008_1l_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = mis2008_1l_write_register, + .pfnReadReg = mis2008_1l_read_register, + .pfnSetBusInfo = mis2008_1l_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 = mis2008_1l_probe, +}; diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008_1L/mis2008_1l_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008_1L/mis2008_1l_cmos_ex.h new file mode 100644 index 00000000..5e30acf4 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008_1L/mis2008_1l_cmos_ex.h @@ -0,0 +1,79 @@ +#ifndef __MIS2008_1L_CMOS_EX_H_ +#define __MIS2008_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 mis2008_1l_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_FLIP_MIRROR_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _MIS2008_1L_MODE_E { + MIS2008_1L_MODE_1080P30 = 0, + MIS2008_1L_MODE_NUM +} MIS2008_1L_MODE_E; + +typedef struct _MIS2008_1L_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]; +} MIS2008_1L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastMIS2008_1L[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunMIS2008_1L_BusInfo[]; +extern CVI_U16 g_au16MIS2008_1L_GainMode[]; +extern CVI_U16 g_au16MIS2008_1L_L2SMode[]; +extern CVI_U8 mis2008_1l_i2c_addr; +extern const CVI_U32 mis2008_1l_addr_byte; +extern const CVI_U32 mis2008_1l_data_byte; +extern void mis2008_1l_init(VI_PIPE ViPipe); +extern void mis2008_1l_exit(VI_PIPE ViPipe); +extern void mis2008_1l_standby(VI_PIPE ViPipe); +extern void mis2008_1l_restart(VI_PIPE ViPipe); +extern int mis2008_1l_write_register(VI_PIPE ViPipe, int addr, int data); +extern int mis2008_1l_read_register(VI_PIPE ViPipe, int addr); +extern void mis2008_1l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int mis2008_1l_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __MIS2008_1L_CMOS_EX_H_ */ \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008_1L/mis2008_1l_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008_1L/mis2008_1l_cmos_param.h new file mode 100644 index 00000000..4e08c874 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008_1L/mis2008_1l_cmos_param.h @@ -0,0 +1,126 @@ +#ifndef __MIS2008_1L_CMOS_PARAM_H_ +#define __MIS2008_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 "mis2008_1l_cmos_ex.h" + +static const MIS2008_1L_MODE_S g_astMIS2008_1L_mode[MIS2008_1L_MODE_NUM] = { + [MIS2008_1L_MODE_1080P30] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1928, + .u32Height = 1088, + }, + .stWndRect = { + .s32X = 8, + .s32Y = 8, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1928, + .u32Height = 1088, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1, /* 1500 * 30 / 0x7FFF*/ + .u32HtsDef = 2200, + .u32VtsDef = 1125, + .stExp[0] = {//exp_time + .u32Min = 1, + .u32Max = 1125 - 1, //exp_max + .u32Def = 128, + .u32Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 16128, + .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 = {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 mis2008_1l_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, -1, -1}, + .pn_swap = {1, 1, 0, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 8, + }, + }, + .mclk = { + .cam = 1, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __MIS2008_1L_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008_1L/mis2008_1l_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008_1L/mis2008_1l_sensor_ctl.c new file mode 100644 index 00000000..06595af4 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/imgds_mis2008_1L/mis2008_1l_sensor_ctl.c @@ -0,0 +1,393 @@ +#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 "mis2008_1l_cmos_ex.h" + +static void mis2008_1l_linear_1080p30_init(VI_PIPE ViPipe); + +CVI_U8 mis2008_1l_i2c_addr = 0x30; /* I2C Address of MIS2008_1L */ +const CVI_U32 mis2008_1l_addr_byte = 2; +const CVI_U32 mis2008_1l_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int mis2008_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_aunMIS2008_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, mis2008_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 mis2008_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 mis2008_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 (mis2008_1l_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, mis2008_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, mis2008_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 (mis2008_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 mis2008_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 (mis2008_1l_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (mis2008_1l_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, mis2008_1l_addr_byte + mis2008_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 mis2008_1l_standby(VI_PIPE ViPipe) +{ + mis2008_1l_write_register(ViPipe, 0x3006, 0x02); +} + +void mis2008_1l_restart(VI_PIPE ViPipe) +{ + mis2008_1l_write_register(ViPipe, 0x3006, 0x01); +} + +void mis2008_1l_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastMIS2008_1L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + mis2008_1l_write_register(ViPipe, + g_pastMIS2008_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastMIS2008_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define MIS2008_1L_CHIP_ID_HI_ADDR 0x3000 +#define MIS2008_1L_CHIP_ID_LO_ADDR 0x3001 +#define MIS2008_1L_CHIP_ID 0x2008 + +int mis2008_1l_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + if (mis2008_1l_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + delay_ms(5); + + nVal = mis2008_1l_read_register(ViPipe, MIS2008_1L_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 = mis2008_1l_read_register(ViPipe, MIS2008_1L_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 != MIS2008_1L_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void mis2008_1l_init(VI_PIPE ViPipe) +{ + mis2008_1l_i2c_init(ViPipe); + + mis2008_1l_linear_1080p30_init(ViPipe); + + g_pastMIS2008_1L[ViPipe]->bInit = CVI_TRUE; +} + +void mis2008_1l_exit(VI_PIPE ViPipe) +{ + mis2008_1l_i2c_exit(ViPipe); +} + +/* 1080p30 */ +static void mis2008_1l_linear_1080p30_init(VI_PIPE ViPipe) +{ + /* [ParaList] */ + mis2008_1l_write_register(ViPipe, 0x300a, 0x01); + mis2008_1l_write_register(ViPipe, 0x300a, 0x01); + mis2008_1l_write_register(ViPipe, 0x3006, 0x02); + mis2008_1l_write_register(ViPipe, 0x3201, 0x65); + mis2008_1l_write_register(ViPipe, 0x3200, 0x04); + mis2008_1l_write_register(ViPipe, 0x3203, 0x98); + mis2008_1l_write_register(ViPipe, 0x3202, 0x08); + mis2008_1l_write_register(ViPipe, 0x3205, 0x04); + mis2008_1l_write_register(ViPipe, 0x3204, 0x00); + mis2008_1l_write_register(ViPipe, 0x3207, 0x43); + mis2008_1l_write_register(ViPipe, 0x3206, 0x04); + mis2008_1l_write_register(ViPipe, 0x3209, 0x04); + mis2008_1l_write_register(ViPipe, 0x3208, 0x00); + mis2008_1l_write_register(ViPipe, 0x320b, 0x8b); + mis2008_1l_write_register(ViPipe, 0x320a, 0x07); + mis2008_1l_write_register(ViPipe, 0x3007, 0x00); + mis2008_1l_write_register(ViPipe, 0x3300, 0x21); + mis2008_1l_write_register(ViPipe, 0x3301, 0x00); + mis2008_1l_write_register(ViPipe, 0x3302, 0x00); + mis2008_1l_write_register(ViPipe, 0x3303, 0x06); + mis2008_1l_write_register(ViPipe, 0x330d, 0x00); + mis2008_1l_write_register(ViPipe, 0x330b, 0x00); + mis2008_1l_write_register(ViPipe, 0x330f, 0x0f); + mis2008_1l_write_register(ViPipe, 0x3013, 0x00); + mis2008_1l_write_register(ViPipe, 0x3637, 0x1e); + mis2008_1l_write_register(ViPipe, 0x3900, 0x07); + mis2008_1l_write_register(ViPipe, 0x2107, 0x00); + mis2008_1l_write_register(ViPipe, 0x330e, 0x00); + mis2008_1l_write_register(ViPipe, 0x3900, 0x07); + mis2008_1l_write_register(ViPipe, 0x2108, 0x01); + mis2008_1l_write_register(ViPipe, 0x3c40, 0x8c); + mis2008_1l_write_register(ViPipe, 0x3c42, 0x01); + mis2008_1l_write_register(ViPipe, 0x3b01, 0x3f); + mis2008_1l_write_register(ViPipe, 0x3b03, 0x3f); + mis2008_1l_write_register(ViPipe, 0x3902, 0x01); + mis2008_1l_write_register(ViPipe, 0x3904, 0x00); + mis2008_1l_write_register(ViPipe, 0x3903, 0x00); + mis2008_1l_write_register(ViPipe, 0x3906, 0x1e); + mis2008_1l_write_register(ViPipe, 0x3905, 0x00); + mis2008_1l_write_register(ViPipe, 0x3908, 0x71); + mis2008_1l_write_register(ViPipe, 0x3907, 0x10); + mis2008_1l_write_register(ViPipe, 0x390a, 0xff); + mis2008_1l_write_register(ViPipe, 0x3909, 0x1f); + mis2008_1l_write_register(ViPipe, 0x390c, 0x67); + mis2008_1l_write_register(ViPipe, 0x390b, 0x03); + mis2008_1l_write_register(ViPipe, 0x390e, 0x77); + mis2008_1l_write_register(ViPipe, 0x390d, 0x00); + mis2008_1l_write_register(ViPipe, 0x3910, 0x71); + mis2008_1l_write_register(ViPipe, 0x390f, 0x10); + mis2008_1l_write_register(ViPipe, 0x3912, 0xff); + mis2008_1l_write_register(ViPipe, 0x3911, 0x1f); + mis2008_1l_write_register(ViPipe, 0x3919, 0x00); + mis2008_1l_write_register(ViPipe, 0x3918, 0x00); + mis2008_1l_write_register(ViPipe, 0x391b, 0x91); + mis2008_1l_write_register(ViPipe, 0x391a, 0x01); + mis2008_1l_write_register(ViPipe, 0x3983, 0x5a); + mis2008_1l_write_register(ViPipe, 0x3982, 0x00); + mis2008_1l_write_register(ViPipe, 0x3985, 0x0f); + mis2008_1l_write_register(ViPipe, 0x3984, 0x00); + mis2008_1l_write_register(ViPipe, 0x391d, 0x00); + mis2008_1l_write_register(ViPipe, 0x391c, 0x00); + mis2008_1l_write_register(ViPipe, 0x391f, 0x65); + mis2008_1l_write_register(ViPipe, 0x391e, 0x10); + mis2008_1l_write_register(ViPipe, 0x3921, 0xff); + mis2008_1l_write_register(ViPipe, 0x3920, 0x1f); + mis2008_1l_write_register(ViPipe, 0x3923, 0xff); + mis2008_1l_write_register(ViPipe, 0x3922, 0x1f); + mis2008_1l_write_register(ViPipe, 0x3932, 0x00); + mis2008_1l_write_register(ViPipe, 0x3931, 0x00); + mis2008_1l_write_register(ViPipe, 0x3934, 0x65); + mis2008_1l_write_register(ViPipe, 0x3933, 0x01); + mis2008_1l_write_register(ViPipe, 0x393f, 0x6c); + mis2008_1l_write_register(ViPipe, 0x393e, 0x00); + mis2008_1l_write_register(ViPipe, 0x3941, 0x67); + mis2008_1l_write_register(ViPipe, 0x3940, 0x00); + mis2008_1l_write_register(ViPipe, 0x3943, 0x55); + mis2008_1l_write_register(ViPipe, 0x3942, 0x01); + mis2008_1l_write_register(ViPipe, 0x3945, 0xc2); + mis2008_1l_write_register(ViPipe, 0x3944, 0x02); + mis2008_1l_write_register(ViPipe, 0x3925, 0x95); + mis2008_1l_write_register(ViPipe, 0x3924, 0x00); + mis2008_1l_write_register(ViPipe, 0x3927, 0xe1); + mis2008_1l_write_register(ViPipe, 0x3926, 0x02); + mis2008_1l_write_register(ViPipe, 0x3947, 0x74); + mis2008_1l_write_register(ViPipe, 0x3946, 0x01); + mis2008_1l_write_register(ViPipe, 0x3949, 0xda); + mis2008_1l_write_register(ViPipe, 0x3948, 0x0e); + mis2008_1l_write_register(ViPipe, 0x394b, 0x42); + mis2008_1l_write_register(ViPipe, 0x394a, 0x03); + mis2008_1l_write_register(ViPipe, 0x394d, 0xf2); + mis2008_1l_write_register(ViPipe, 0x394c, 0x01); + mis2008_1l_write_register(ViPipe, 0x3913, 0x01); + mis2008_1l_write_register(ViPipe, 0x3915, 0x0f); + mis2008_1l_write_register(ViPipe, 0x3914, 0x00); + mis2008_1l_write_register(ViPipe, 0x3917, 0x67); + mis2008_1l_write_register(ViPipe, 0x3916, 0x03); + mis2008_1l_write_register(ViPipe, 0x392a, 0x1e); + mis2008_1l_write_register(ViPipe, 0x3929, 0x00); + mis2008_1l_write_register(ViPipe, 0x392c, 0x0f); + mis2008_1l_write_register(ViPipe, 0x392b, 0x00); + mis2008_1l_write_register(ViPipe, 0x392e, 0x0f); + mis2008_1l_write_register(ViPipe, 0x392d, 0x00); + mis2008_1l_write_register(ViPipe, 0x3930, 0x6e); + mis2008_1l_write_register(ViPipe, 0x392f, 0x03); + mis2008_1l_write_register(ViPipe, 0x397f, 0x00); + mis2008_1l_write_register(ViPipe, 0x397e, 0x00); + mis2008_1l_write_register(ViPipe, 0x3981, 0x77); + mis2008_1l_write_register(ViPipe, 0x3980, 0x00); + mis2008_1l_write_register(ViPipe, 0x395d, 0x80); + mis2008_1l_write_register(ViPipe, 0x395c, 0x10); + mis2008_1l_write_register(ViPipe, 0x3962, 0x9e); + mis2008_1l_write_register(ViPipe, 0x3961, 0x10); + mis2008_1l_write_register(ViPipe, 0x3967, 0x50); + mis2008_1l_write_register(ViPipe, 0x3977, 0x22); + mis2008_1l_write_register(ViPipe, 0x3976, 0x00); + mis2008_1l_write_register(ViPipe, 0x3978, 0x00); + mis2008_1l_write_register(ViPipe, 0x3979, 0x04); + mis2008_1l_write_register(ViPipe, 0x396d, 0xc2); + mis2008_1l_write_register(ViPipe, 0x396c, 0x02); + mis2008_1l_write_register(ViPipe, 0x396f, 0xc2); + mis2008_1l_write_register(ViPipe, 0x396e, 0x02); + mis2008_1l_write_register(ViPipe, 0x3971, 0xc2); + mis2008_1l_write_register(ViPipe, 0x3970, 0x02); + mis2008_1l_write_register(ViPipe, 0x3973, 0xc2); + mis2008_1l_write_register(ViPipe, 0x3972, 0x02); + mis2008_1l_write_register(ViPipe, 0x3900, 0x01); + mis2008_1l_write_register(ViPipe, 0x3600, 0x00); + mis2008_1l_write_register(ViPipe, 0x3707, 0x00); + mis2008_1l_write_register(ViPipe, 0x3708, 0x80); + mis2008_1l_write_register(ViPipe, 0x3709, 0x00); + mis2008_1l_write_register(ViPipe, 0x370a, 0x80); + mis2008_1l_write_register(ViPipe, 0x370b, 0x00); + mis2008_1l_write_register(ViPipe, 0x370c, 0x80); + mis2008_1l_write_register(ViPipe, 0x370d, 0x00); + mis2008_1l_write_register(ViPipe, 0x370e, 0x80); + mis2008_1l_write_register(ViPipe, 0x3012, 0x01); + mis2008_1l_write_register(ViPipe, 0x3600, 0x13); + mis2008_1l_write_register(ViPipe, 0x3601, 0x02); + mis2008_1l_write_register(ViPipe, 0x360e, 0x00); + mis2008_1l_write_register(ViPipe, 0x360f, 0x00); + mis2008_1l_write_register(ViPipe, 0x3610, 0x02); + mis2008_1l_write_register(ViPipe, 0x3707, 0x00); + mis2008_1l_write_register(ViPipe, 0x3708, 0x40); + mis2008_1l_write_register(ViPipe, 0x3709, 0x00); + mis2008_1l_write_register(ViPipe, 0x370a, 0x40); + mis2008_1l_write_register(ViPipe, 0x370b, 0x00); + mis2008_1l_write_register(ViPipe, 0x370c, 0x40); + mis2008_1l_write_register(ViPipe, 0x370d, 0x00); + mis2008_1l_write_register(ViPipe, 0x370e, 0x40); + mis2008_1l_write_register(ViPipe, 0x3800, 0x01); + mis2008_1l_write_register(ViPipe, 0x3a03, 0x03); + mis2008_1l_write_register(ViPipe, 0x3a02, 0x0b); + mis2008_1l_write_register(ViPipe, 0x3a08, 0x34); + mis2008_1l_write_register(ViPipe, 0x3a1b, 0x54); + mis2008_1l_write_register(ViPipe, 0x3a1e, 0x80); + mis2008_1l_write_register(ViPipe, 0x3100, 0x04); + mis2008_1l_write_register(ViPipe, 0x3101, 0x64); + mis2008_1l_write_register(ViPipe, 0x3a1c, 0x10); + mis2008_1l_write_register(ViPipe, 0x3a0C, 0x04); + mis2008_1l_write_register(ViPipe, 0x3a0D, 0x12); + mis2008_1l_write_register(ViPipe, 0x3a0E, 0x15); + mis2008_1l_write_register(ViPipe, 0x3a0F, 0x18); + mis2008_1l_write_register(ViPipe, 0x3a10, 0x20); + mis2008_1l_write_register(ViPipe, 0x3a11, 0x3c); + mis2008_1l_write_register(ViPipe, 0x3a19, 0x10); + mis2008_1l_write_register(ViPipe, 0x3006, 0x00); + + mis2008_1l_default_reg_init(ViPipe); + + + delay_ms(100); + + printf("ViPipe:%d,===MIS2008_1L 1080P 30fps 12bit LINE Init OK!===\n", ViPipe); +} + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/lontium_lt6911/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/lontium_lt6911/Makefile new file mode 100644 index 00000000..8590b964 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/lontium_lt6911/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_lt6911.a +TARGET_SO = $(MW_LIB)/libsns_lt6911.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/lontium_lt6911/lt6911_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/lontium_lt6911/lt6911_cmos.c new file mode 100644 index 00000000..cceeeb08 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/lontium_lt6911/lt6911_cmos.c @@ -0,0 +1,423 @@ +#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 "lt6911_cmos_ex.h" +#include "lt6911_cmos_param.h" + +#define LT6911_ID 6911 + +#define INPUT_WIDTH (1920) +#define INPUT_HEIGHT (1080) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastLt6911[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define LT6911_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastLt6911[dev]) +#define LT6911_SENSOR_SET_CTX(dev, pstCtx) (g_pastLt6911[dev] = pstCtx) +#define LT6911_SENSOR_RESET_CTX(dev) (g_pastLt6911[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunLt6911_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****lt6911 Lines Range*****/ + + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + (void) ViPipe; + (void) pstAeSnsDft; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + (void) ViPipe; + (void) pu32AgainLin; + (void) pu32AgainDb; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + (void) ViPipe; + (void) pu32DgainLin; + (void) pu32DgainDb; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + (void) ViPipe; + (void) pu32Again; + (void) pu32Dgain; + + 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_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; + + 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_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const LT6911_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + LT6911_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astLt6911_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "not support wdr mode\n"); + } + + 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_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + LT6911_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + + //pstSnsState->bSyncInit, pstSnsRegsInfo->bConfig); + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunLt6911_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + pstSnsState->bSyncInit = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } + + 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); + LT6911_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = LT6911_MODE_NORMAL; + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + (void) ViPipe; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + LT6911_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->u8ImgMode = LT6911_MODE_NORMAL; +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + LT6911_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, <6911_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astLt6911_mode[0].astImg[pstSnsState->u8ImgMode].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astLt6911_mode[0].astImg[pstSnsState->u8ImgMode].stSnsSize.u32Height; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + (void) ViPipe; + (void) u8Mode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = <6911_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 = lt6911_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = lt6911_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_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ + +static CVI_S32 lt6911_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunLt6911_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_param_fix(CVI_VOID) +{ + LT6911_MODE_S *pstMode = &g_astLt6911_mode[LT6911_MODE_NORMAL]; + + pstMode->astImg[0].stSnsSize.u32Width = INPUT_WIDTH; + pstMode->astImg[0].stSnsSize.u32Height = INPUT_HEIGHT; + pstMode->astImg[0].stWndRect.u32Width = INPUT_WIDTH; + pstMode->astImg[0].stWndRect.u32Height = INPUT_HEIGHT; + pstMode->astImg[0].stMaxSize.u32Width = INPUT_WIDTH; + pstMode->astImg[0].stMaxSize.u32Height = INPUT_HEIGHT; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + LT6911_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)); + + LT6911_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + LT6911_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + LT6911_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; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + sensor_param_fix(); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = LT6911_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; + } + + 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, LT6911_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, LT6911_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, LT6911_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) +{ + (void) ViPipe; + (void) pstInitAttr; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return lt6911_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsLT6911_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = CVI_NULL, + .pfnRestart = CVI_NULL, + .pfnMirrorFlip = CVI_NULL, + .pfnWriteReg = lt6911_write, + .pfnReadReg = lt6911_read, + .pfnSetBusInfo = lt6911_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, +}; \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/lontium_lt6911/lt6911_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/lontium_lt6911/lt6911_cmos_ex.h new file mode 100644 index 00000000..b3863cad --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/lontium_lt6911/lt6911_cmos_ex.h @@ -0,0 +1,63 @@ +#ifndef __LT6911_CMOS_EX_H_ +#define __LT6911_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 lt6911_linear_regs_e { + LINEAR_REGS_NUM +}; + + +typedef enum _LT6911_MODE_E { + LT6911_MODE_NONE, + LT6911_MODE_NORMAL, + LT6911_MODE_NUM +} LT6911_MODE_E; + + +typedef struct _LT6911_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + char name[64]; +} LT6911_MODE_S; + + +extern CVI_U8 lt6911_i2c_addr; +extern const CVI_U32 lt6911_addr_byte; +extern const CVI_U32 lt6911_data_byte; +extern void lt6911_init(VI_PIPE ViPipe); +extern void lt6911_exit(VI_PIPE ViPipe); +extern void lt6911_standby(VI_PIPE ViPipe); +extern void lt6911_restart(VI_PIPE ViPipe); +extern int lt6911_write(VI_PIPE ViPipe, int addr, int data); +extern int lt6911_read(VI_PIPE ViPipe, int addr); +extern void lt6911_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int lt6911_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __LT6911_CMOS_EX_H_ */ \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/lontium_lt6911/lt6911_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/lontium_lt6911/lt6911_cmos_param.h new file mode 100644 index 00000000..46ccbdd7 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/lontium_lt6911/lt6911_cmos_param.h @@ -0,0 +1,75 @@ +#ifndef __LT6911_CMOS_PARAM_H_ +#define __LT6911_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 "lt6911_cmos_ex.h" + +// not real time resolution +#define WIDTH 3840//3840 1920 +#define HEIGHT 2160//2160 1080 + +static LT6911_MODE_S g_astLt6911_mode[LT6911_MODE_NUM] = { + [LT6911_MODE_NORMAL] = { + .name = "lt6911", + .astImg[0] = { + .stSnsSize = { + .u32Width = WIDTH, + .u32Height = HEIGHT, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = WIDTH, + .u32Height = HEIGHT, + }, + .stMaxSize = { + .u32Width = WIDTH, + .u32Height = HEIGHT, + }, + }, + }, +}; + +struct combo_dev_attr_s lt6911_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_600M, + .mipi_attr = { + .raw_data_type = YUV422_8BIT, + .lane_id = {2, 0, 1, 3, 4}, //3, 0, 1, 2, 4 ; 1, 4, 3, 2, 0 2, 0, 1, 3, 4 3, 1, 2, 4, 0 + .pn_swap = {1, 1, 1, 1, 1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 8, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_NONE, + }, + .devno = 1, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __LT6911_CMOS_PARAM_H_ */ \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/lontium_lt6911/lt6911_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/lontium_lt6911/lt6911_sensor_ctl.c new file mode 100644 index 00000000..3df0b4eb --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/lontium_lt6911/lt6911_sensor_ctl.c @@ -0,0 +1,215 @@ +#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 "lt6911_cmos_ex.h" + +#define LT6911_I2C_DEV 3 +#define LT6911_I2C_BANK_ADDR 0xff + +CVI_U8 lt6911_i2c_addr = 0x2b; +const CVI_U32 lt6911_addr_byte = 1; +const CVI_U32 lt6911_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int lt6911_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", LT6911_I2C_DEV); + + 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", LT6911_I2C_DEV); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, lt6911_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 lt6911_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 lt6911_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 (lt6911_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, lt6911_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, lt6911_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (lt6911_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "vipipe:%d i2c r 0x%x = 0x%x\n", ViPipe, addr, data); + return data; +} + +int lt6911_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 (lt6911_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + } + buf[idx] = addr & 0xff; + idx++; + + + if (lt6911_data_byte == 2) { + buf[idx] = (data >> 8) & 0xff; + idx++; + } + buf[idx] = data & 0xff; + idx++; + + ret = write(g_fd[ViPipe], buf, lt6911_addr_byte + lt6911_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + // ret = read(g_fd[ViPipe], buf, lt6911_addr_byte + lt6911_data_byte); + syslog(LOG_DEBUG, "ViPipe:%d i2c w 0x%x 0x%x\n", ViPipe, addr, data); + return CVI_SUCCESS; +} + +static int lt6911_i2c_read(VI_PIPE ViPipe, int RegAddr) +{ + uint8_t bank = RegAddr >> 8; + uint8_t addr = RegAddr & 0xff; + + lt6911_write_register(ViPipe, LT6911_I2C_BANK_ADDR, bank); + return lt6911_read_register(ViPipe, addr); +} + +static int lt6911_i2c_write(VI_PIPE ViPipe, int RegAddr, int data) +{ + uint8_t bank = RegAddr >> 8; + uint8_t addr = RegAddr & 0xff; + + lt6911_write_register(ViPipe, LT6911_I2C_BANK_ADDR, bank); + return lt6911_write_register(ViPipe, addr, data); +} + +int lt6911_read(VI_PIPE ViPipe, int addr) +{ + int data = 0; + + lt6911_i2c_write(ViPipe, 0x80ee, 0x01); + data = lt6911_i2c_read(ViPipe, addr); + lt6911_i2c_write(ViPipe, 0x80ee, 0x00); + return data; +} + +int lt6911_write(VI_PIPE ViPipe, int addr, int data) +{ + lt6911_i2c_write(ViPipe, 0x80ee, 0x01); + lt6911_i2c_write(ViPipe, addr, data); + lt6911_i2c_write(ViPipe, 0x80ee, 0x00); + return CVI_SUCCESS; +} + +#define LT6911_CHIP_ID_ADDR_H 0xa000 +#define LT6911_CHIP_ID_ADDR_L 0xa001 +#define LT6911_CHIP_ID 0x1605 + +int lt6911_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (lt6911_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = lt6911_read(ViPipe, LT6911_CHIP_ID_ADDR_H); + nVal2 = lt6911_read(ViPipe, LT6911_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + printf("data:%02x %02x\n", nVal, nVal2); + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != LT6911_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void lt6911_init(VI_PIPE ViPipe) +{ + lt6911_i2c_init(ViPipe); +} + +void lt6911_exit(VI_PIPE ViPipe) +{ + lt6911_i2c_exit(ViPipe); +} \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/nextchip_n5/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/nextchip_n5/Makefile new file mode 100644 index 00000000..a9cbf405 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/nextchip_n5/n5_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/nextchip_n5/n5_cmos.c new file mode 100644 index 00000000..fc580cff --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/nextchip_n5/n5_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/nextchip_n5/n5_cmos_ex.h new file mode 100644 index 00000000..1edfdcaa --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/nextchip_n5/n5_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/nextchip_n5/n5_cmos_param.h new file mode 100644 index 00000000..088dfe8c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/nextchip_n5/n5_sensor_ctrl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/nextchip_n5/n5_sensor_ctrl.c new file mode 100644 index 00000000..bfa61781 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/nextchip_n6/n6_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/nextchip_n6/n6_cmos_ex.h new file mode 100644 index 00000000..485a8021 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/nextchip_n6/n6_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/nextchip_n6/n6_cmos_param.h new file mode 100644 index 00000000..0698002b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/nextchip_n6/n6_sensor_ctrl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/nextchip_n6/n6_sensor_ctrl.c new file mode 100644 index 00000000..f803c9c1 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 +#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 EPS 1e-7 +#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); +static CVI_FLOAT OTP_rate; +static CVI_BOOL HCG_EN; +/*****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_HCG_ADDR1 0x376C +#define OS04A10_HCG_ADDR2 0x3C55 + +#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 : 1 + * max : vts - 8 + * step : 1 + */ + u32TmpIntTime = (u32TmpIntTime > maxExp) ? maxExp : u32TmpIntTime; + u32TmpIntTime = u32TmpIntTime >= 1 ? u32TmpIntTime : 1; + 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; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + (void) ViPipe; + OS04A10_SENSOR_GET_CTX(ViPipe, pstSnsState); + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + CMOS_CHECK_POINTER(pstSnsState); + float rate; + + if (OTP_rate < 1.0) + OTP_rate = (((os04a10_read_register(ViPipe, 0x77fe) * 256) + os04a10_read_register(ViPipe, 0x77ff)) + * 1.0) / 256; + if (*pu32AgainLin > 15900) { + rate = OTP_rate; + HCG_EN = CVI_TRUE; + } else { + rate = 1; + HCG_EN = CVI_FALSE; + } + + if (*pu32AgainLin >= (unsigned int)(Again_table[63] * rate)) { + *pu32AgainLin = (unsigned int)(Again_table[63] * rate); + *pu32AgainDb = 63; + return CVI_SUCCESS; + } + + for (i = 1; i < 64; i++) { + if (*pu32AgainLin < (unsigned int)(Again_table[i] * rate)) { + *pu32AgainLin = (unsigned int)(Again_table[i - 1] * rate); + *pu32AgainDb = i - 1; + break; + } + } + if (*pu32AgainLin < 15872 && fabs(rate - OTP_rate) <= EPS) + *pu32AgainLin = 15872; + + 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 */ + if (HCG_EN) { + pstSnsRegsInfo->astI2cData[LINEAR_HCG_0].u32Data = 0x00; + pstSnsRegsInfo->astI2cData[LINEAR_HCG_1].u32Data = 0xcb; + } else { + pstSnsRegsInfo->astI2cData[LINEAR_HCG_0].u32Data = 0x10; + pstSnsRegsInfo->astI2cData[LINEAR_HCG_1].u32Data = 0x08; + } + /* 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 { + if (HCG_EN) { + pstSnsRegsInfo->astI2cData[WDR2_HCG_0].u32Data = 0x04; + pstSnsRegsInfo->astI2cData[WDR2_HCG_1].u32Data = 0xcb; + } else { + pstSnsRegsInfo->astI2cData[WDR2_HCG_0].u32Data = 0x34; + pstSnsRegsInfo->astI2cData[WDR2_HCG_1].u32Data = 0x08; + } + /* 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 = 1; + /* + * 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; + pstI2c_data[i].bvblankUpdate = CVI_FALSE; + } + + 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; + pstI2c_data[WDR2_HCG_0].u32RegAddr = OS04A10_HCG_ADDR1; + pstI2c_data[WDR2_HCG_0].bvblankUpdate = CVI_TRUE; + pstI2c_data[WDR2_HCG_0].u8DelayFrmNum = 3; + pstI2c_data[WDR2_HCG_1].u32RegAddr = OS04A10_HCG_ADDR2; + pstI2c_data[WDR2_HCG_1].bvblankUpdate = CVI_TRUE; + pstI2c_data[WDR2_HCG_1].u8DelayFrmNum = 3; + 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; + pstI2c_data[LINEAR_HCG_0].u32RegAddr = OS04A10_HCG_ADDR1; + pstI2c_data[LINEAR_HCG_0].bvblankUpdate = CVI_TRUE; + pstI2c_data[LINEAR_HCG_0].u8DelayFrmNum = 3; + pstI2c_data[LINEAR_HCG_1].u32RegAddr = OS04A10_HCG_ADDR2; + pstI2c_data[LINEAR_HCG_1].bvblankUpdate = CVI_TRUE; + pstI2c_data[LINEAR_HCG_1].u8DelayFrmNum = 3; + 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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04a10/os04a10_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04a10/os04a10_cmos_ex.h new file mode 100644 index 00000000..0f14d408 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04a10/os04a10_cmos_ex.h @@ -0,0 +1,121 @@ +#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_HCG_0, + LINEAR_HCG_1, + 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_HCG_0, + WDR2_HCG_1, + 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04a10/os04a10_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04a10/os04a10_cmos_param.h new file mode 100644 index 00000000..a06e5e52 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 = 1484, + .u32VtsDef = 2432, + .stExp[0] = { + .u16Min = 1, + .u16Max = 2432 - 8, + .u16Def = 500, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 68200, + .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 = 2, + .u16Max = 88, + .u16Def = 88, + .u16Step = 1, + }, + .stExp[1] = { + .u16Min = 2, + .u16Max = 0x486 - 4 - 88, + .u16Def = 500, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 68200, + .u32Def = 1024, + .u32Step = 1, + }, + .stAgain[1] = { + .u32Min = 1024, + .u32Max = 68200, + .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_400M, + .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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04a10/os04a10_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04a10/os04a10_sensor_ctl.c new file mode 100644 index 00000000..d1476b79 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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, 0x5c); + 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, 0xd0); + 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, 0x09); + os04a10_write_register(ViPipe, 0x380f, 0x80); + 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, 0x0d); + 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04c10/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04c10/Makefile new file mode 100644 index 00000000..f9ec2996 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04c10/os04c10_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04c10/os04c10_cmos.c new file mode 100644 index 00000000..1006e82f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04c10/os04c10_cmos.c @@ -0,0 +1,1166 @@ +#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 "os04c10_cmos_ex.h" +#include "os04c10_cmos_param.h" + +#define EPS 1e-7 +#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); +static CVI_FLOAT OTP_rate; +static CVI_BOOL HCG_EN; +/*****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_LINEAR_HCG_ADDR 0x3798 +#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; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + (void) ViPipe; + OS04C10_SENSOR_GET_CTX(ViPipe, pstSnsState); + + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + CMOS_CHECK_POINTER(pstSnsState); + float rate; + + if (OTP_rate < 1.0) + OTP_rate = (((os04c10_read_register(ViPipe, 0x71e0) * 256) + os04c10_read_register(ViPipe, 0x71e1)) + * 1.0) / 1024; + if (pstSnsState->enWDRMode == WDR_MODE_NONE && *pu32AgainLin > 15900) { + rate = OTP_rate; + HCG_EN = CVI_TRUE; + } else { + rate = 1; + HCG_EN = CVI_FALSE; + } + + if (*pu32AgainLin >= (unsigned int)(gain_table[63] * rate)) { + *pu32AgainLin = (unsigned int)(gain_table[63] * rate); + *pu32AgainDb = (63 - 48) * 64 + 1024; + return CVI_SUCCESS; + } + + for (i = 1; i < 64; i++) { + if (*pu32AgainLin < (unsigned int)(gain_table[i] * rate)) { + *pu32AgainLin = (unsigned int)(gain_table[i - 1] * rate); + 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; + } + } + + if (*pu32AgainLin < 15872 && fabs(rate - OTP_rate) <= EPS) + *pu32AgainLin = 15872; + + 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) { + if (HCG_EN) { + pstSnsRegsInfo->astI2cData[LINEAR_HCG].u32Data = 0x40; + } else { + pstSnsRegsInfo->astI2cData[LINEAR_HCG].u32Data = 0xc0; + } + /* 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; + pstI2c_data[i].bvblankUpdate = CVI_FALSE; + } + + 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; + pstI2c_data[LINEAR_HCG].u32RegAddr = OS04C10_LINEAR_HCG_ADDR; + pstI2c_data[LINEAR_HCG].bvblankUpdate = CVI_TRUE; + pstI2c_data[LINEAR_HCG].u8DelayFrmNum = 3; + 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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04c10/os04c10_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04c10/os04c10_cmos_ex.h new file mode 100644 index 00000000..ca071a9c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04c10/os04c10_cmos_ex.h @@ -0,0 +1,122 @@ +#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_HCG, + 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04c10/os04c10_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04c10/os04c10_cmos_param.h new file mode 100644 index 00000000..e2e87ea1 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 = 45495, + .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 = 45495, + .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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04c10/os04c10_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os04c10/os04c10_sensor_ctl.c new file mode 100644 index 00000000..2cc6f667 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os08a20/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os08a20/Makefile new file mode 100644 index 00000000..3a9655ed --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os08a20/os08a20_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os08a20/os08a20_cmos.c new file mode 100644 index 00000000..71b0a78d --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os08a20/os08a20_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os08a20/os08a20_cmos_ex.h new file mode 100644 index 00000000..ce48bf90 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os08a20/os08a20_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os08a20/os08a20_cmos_param.h new file mode 100644 index 00000000..692e7313 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os08a20/os08a20_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_os08a20/os08a20_sensor_ctl.c new file mode 100644 index 00000000..f9bfe49c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov2685/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov2685/Makefile new file mode 100644 index 00000000..6d272be9 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov2685/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)/libov_ov2685.a +TARGET_SO = $(MW_LIB)/libov_ov2685.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov2685/ov2685_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov2685/ov2685_cmos.c new file mode 100644 index 00000000..23cd5f92 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov2685/ov2685_cmos.c @@ -0,0 +1,972 @@ +#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 "ov2685_cmos_ex.h" +#include "ov2685_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 OV2685_ID 2685 +#define OV2685_I2C_ADDR_1 0x10 +#define OV2685_I2C_ADDR_2 0x3c +#define OV2685_I2C_ADDR_IS_VALID(addr) ((addr) == OV2685_I2C_ADDR_1 || (addr) == OV2685_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ***************************************************************************/ + +ISP_SNS_STATE_S *g_pastOv2685[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define OV2685_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastOv2685[dev]) +#define OV2685_SENSOR_SET_CTX(dev, pstCtx) (g_pastOv2685[dev] = pstCtx) +#define OV2685_SENSOR_RESET_CTX(dev) (g_pastOv2685[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunOv2685_BusInfo[VI_MAX_PIPE_NUM] = { + // for licheervnano + [0] = { .s8I2cDev = 4}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeOv2685_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +CVI_U16 g_au16Ov2685_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); +/*****Ov2685 Lines Range*****/ +#define OV2685_FULL_LINES_MAX (0x3fff) + +/*****Ov2685 Register Address*****/ +#define OV2685_EXP_H_ADDR 0x0202 //bit[13:8] +#define OV2685_EXP_L_ADDR 0x0203 + +#define OV2685_AGAIN_H_ADDR 0x02b4 //bit[10:8] +#define OV2685_AGAIN_L_ADDR 0x02b3 +#define OV2685_COL_AGAIN_H_ADDR 0x02b8 //bit[13:8] +#define OV2685_COL_AGAIN_L_ADDR 0x02b9 +#define OV2685_DGAIN_H_ADDR 0x020e //bit[9:6] +#define OV2685_DGAIN_L_ADDR 0x020f //bit[5:0] +#define OV2685_AGAIN_MAG1_ADDR 0x0515 +#define OV2685_AGAIN_MAG2_ADDR 0x0519 +#define OV2685_AGAIN_MAG3_ADDR 0x02d9 + +#define OV2685_VTS_H_ADDR 0x0340 //bit[13:8] +#define OV2685_VTS_L_ADDR 0x0341 + +#define OV2685_FLIP_MIRROR_ADDR 0x0101 +#define OV2685_FRAME_BUF_ADDR 0x031D + +#define OV2685_RES_IS_1600X1200(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); + OV2685_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = OV2685_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_astOv2685_mode[OV2685_MODE_1600X1200P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astOv2685_mode[OV2685_MODE_1600X1200P30].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_astOv2685_mode[OV2685_MODE_1600X1200P30].stExp[0].u16Def; + + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstAeSnsDft->u32MinIntTime = g_astOv2685_mode[OV2685_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); + OV2685_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astOv2685_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astOv2685_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astOv2685_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 > OV2685_FULL_LINES_MAX) ? OV2685_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; + + OV2685_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); + + OV2685_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 OV2685_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV2685_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astOv2685_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); + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV2685_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + switch (u8Mode) { + case WDR_MODE_NONE: + // pstSnsState->u8ImgMode = OV2685_MODE_1600X1200P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOv2685_mode[pstSnsState->u8ImgMode].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)); + + //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); + OV2685_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_aunOv2685_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 = ov2685_i2c_addr; + pstI2c_data[i].u32AddrByteNum = ov2685_addr_byte; + pstI2c_data[i].u32DataByteNum = ov2685_data_byte; + } + + pstI2c_data[LINEAR_EXP_H].u32RegAddr = OV2685_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = OV2685_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = OV2685_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = OV2685_AGAIN_L_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = OV2685_COL_AGAIN_H_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = OV2685_COL_AGAIN_L_ADDR; + pstI2c_data[LINEAR_AGAIN_MAG1].u32RegAddr = OV2685_AGAIN_MAG1_ADDR; + pstI2c_data[LINEAR_AGAIN_MAG2].u32RegAddr = OV2685_AGAIN_MAG2_ADDR; + pstI2c_data[LINEAR_AGAIN_MAG3].u32RegAddr = OV2685_AGAIN_MAG3_ADDR; + pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = OV2685_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = OV2685_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VTS_H].u32RegAddr = OV2685_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = OV2685_VTS_L_ADDR; + pstI2c_data[LINEAR_FLIP_MIRROR].u32RegAddr = OV2685_FLIP_MIRROR_ADDR; + pstI2c_data[LINEAR_FRAME_BUF_ON].u32RegAddr = OV2685_FRAME_BUF_ADDR; + pstI2c_data[LINEAR_FRAME_BUF_ON].u32Data = 0x2D; + pstI2c_data[LINEAR_FRAME_BUF_OFF].u32RegAddr = OV2685_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); + OV2685_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + u8SensorImageMode = OV2685_MODE_1600X1200P30; + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + 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); + } + + 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; + + OV2685_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_aeOv2685_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_aeOv2685_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV2685_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = OV2685_MODE_1600X1200P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOv2685_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astOv2685_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astOv2685_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; + + OV2685_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + // CVI_U8 u8SensorImageMode = 0; + + memcpy(pstRxAttr, &ov2685_rx_attr, sizeof(*pstRxAttr)); + pstRxAttr->img_size.width = g_astOv2685_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astOv2685_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 = &ov2685_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 = ov2685_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = ov2685_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 (OV2685_I2C_ADDR_IS_VALID(s32I2cAddr)) + ov2685_i2c_addr = s32I2cAddr; + else + ov2685_i2c_addr = OV2685_I2C_ADDR_2; +} + +static CVI_S32 ov2685_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunOv2685_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OV2685_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)); + + OV2685_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OV2685_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + OV2685_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 = OV2685_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, OV2685_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, OV2685_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, OV2685_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_au16Ov2685_GainMode[ViPipe] = pstInitAttr->enGainMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return ov2685_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsOv2685_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = ov2685_standby, + .pfnRestart = ov2685_restart, + .pfnWriteReg = ov2685_write_register, + .pfnReadReg = ov2685_read_register, + .pfnSetBusInfo = ov2685_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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov2685/ov2685_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov2685/ov2685_cmos_ex.h new file mode 100644 index 00000000..d1567dd3 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov2685/ov2685_cmos_ex.h @@ -0,0 +1,93 @@ +#ifndef __OV2685_CMOS_EX_H_ +#define __OV2685_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 ov2685_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 _OV2685_MODE_E { + OV2685_MODE_1600X1200P30 = 0, + OV2685_MODE_LINEAR_NUM, + OV2685_MODE_NUM +} OV2685_MODE_E; + +typedef struct _OV2685_STATE_S { + CVI_U32 u32Sexp_MAX; +} OV2685_STATE_S; + +typedef struct _OV2685_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]; +} OV2685_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastOv2685[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunOv2685_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeOv2685_MirrorFip[VI_MAX_PIPE_NUM]; +extern CVI_U8 ov2685_i2c_addr; +extern const CVI_U32 ov2685_addr_byte; +extern const CVI_U32 ov2685_data_byte; +extern void ov2685_init(VI_PIPE ViPipe); +extern void ov2685_exit(VI_PIPE ViPipe); +extern void ov2685_standby(VI_PIPE ViPipe); +extern void ov2685_restart(VI_PIPE ViPipe); +extern int ov2685_write_register(VI_PIPE ViPipe, int addr, int data); +extern int ov2685_read_register(VI_PIPE ViPipe, int addr); +extern int ov2685_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OV2685_CMOS_EX_H_ */ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov2685/ov2685_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov2685/ov2685_cmos_param.h new file mode 100644 index 00000000..7aaa8347 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov2685/ov2685_cmos_param.h @@ -0,0 +1,227 @@ +#ifndef __OV2685_CMOS_PARAM_H_ +#define __OV2685_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 "ov2685_cmos_ex.h" + +static const OV2685_MODE_S g_astOv2685_mode[OV2685_MODE_NUM] = { + [OV2685_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.75, /* 1500 * 30 / 16383 */ + .u32HtsDef = 1500, + .u32VtsDef = 750,//650 + .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_MANUAL, + .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 ov2685_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_600M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {4, 3, 2, -1, -1}, + .pn_swap = {1, 1, 1, 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 /* __OV2685_CMOS_PARAM_H_ */ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov2685/ov2685_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov2685/ov2685_sensor_ctl.c new file mode 100644 index 00000000..17b9297e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov2685/ov2685_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 "ov2685_cmos_ex.h" + +#define OV2685_CHIP_ID_ADDR_H 0x300A +#define OV2685_CHIP_ID_ADDR_L 0x300B +#define OV2685_CHIP_ID 0x2685 + +static void ov2685_linear_720p30_init(VI_PIPE ViPipe); +static void ov2685_linear_1600x1200_30_init(VI_PIPE ViPipe); + +CVI_U8 ov2685_i2c_addr = 0x29; +const CVI_U32 ov2685_addr_byte = 2; +const CVI_U32 ov2685_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int ov2685_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunOv2685_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, ov2685_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 ov2685_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 ov2685_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 (ov2685_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, ov2685_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, ov2685_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (ov2685_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 ov2685_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 (ov2685_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + if (ov2685_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, ov2685_addr_byte + ov2685_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + ret = read(g_fd[ViPipe], buf, ov2685_addr_byte + ov2685_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 ov2685_standby(VI_PIPE ViPipe) +{ + ov2685_write_register(ViPipe, 0x0100, 0x00); + ov2685_write_register(ViPipe, 0x031c, 0xc7); + ov2685_write_register(ViPipe, 0x0317, 0x01); + + printf("ov2685_standby\n"); +} + +void ov2685_restart(VI_PIPE ViPipe) +{ + ov2685_write_register(ViPipe, 0x0317, 0x00); + ov2685_write_register(ViPipe, 0x031c, 0xc6); + ov2685_write_register(ViPipe, 0x0100, 0x09); + + printf("ov2685_restart\n"); +} + +void ov2685_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastOv2685[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + ov2685_write_register(ViPipe, + g_pastOv2685[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastOv2685[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +int ov2685_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (ov2685_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = ov2685_read_register(ViPipe, OV2685_CHIP_ID_ADDR_H); + nVal2 = ov2685_read_register(ViPipe, OV2685_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)) != OV2685_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void ov2685_init(VI_PIPE ViPipe) +{ + // CVI_U8 u8ImgMode; + + ov2685_i2c_init(ViPipe); + + // u8ImgMode = g_pastOv2685[ViPipe]->u8ImgMode; + + ov2685_linear_1600x1200_30_init(ViPipe); + + g_pastOv2685[ViPipe]->bInit = CVI_TRUE; +} + +void ov2685_exit(VI_PIPE ViPipe) +{ + ov2685_i2c_exit(ViPipe); +} + +static void ov2685_linear_1600x1200_30_init(VI_PIPE ViPipe) +{ + ov2685_write_register(ViPipe, 0x0103, 0x0001); + ov2685_write_register(ViPipe, 0x3002, 0x0000); + ov2685_write_register(ViPipe, 0x3016, 0x001c); + ov2685_write_register(ViPipe, 0x3018, 0x0084); + ov2685_write_register(ViPipe, 0x301d, 0x00f0); + ov2685_write_register(ViPipe, 0x3020, 0x0000); + ov2685_write_register(ViPipe, 0x3082, 0x0037); + ov2685_write_register(ViPipe, 0x3083, 0x0003); + ov2685_write_register(ViPipe, 0x3084, 0x0009); + ov2685_write_register(ViPipe, 0x3085, 0x0004); + ov2685_write_register(ViPipe, 0x3086, 0x0000); + ov2685_write_register(ViPipe, 0x3087, 0x0001); + ov2685_write_register(ViPipe, 0x3501, 0x004e); + ov2685_write_register(ViPipe, 0x3502, 0x00e0); + ov2685_write_register(ViPipe, 0x3503, 0x0000); + ov2685_write_register(ViPipe, 0x350b, 0x0036); + ov2685_write_register(ViPipe, 0x3600, 0x00b4); + ov2685_write_register(ViPipe, 0x3603, 0x0035); + ov2685_write_register(ViPipe, 0x3604, 0x0024); + ov2685_write_register(ViPipe, 0x3605, 0x0000); + ov2685_write_register(ViPipe, 0x3620, 0x0024); + ov2685_write_register(ViPipe, 0x3621, 0x0034); + ov2685_write_register(ViPipe, 0x3622, 0x0003); + ov2685_write_register(ViPipe, 0x3628, 0x0010); + ov2685_write_register(ViPipe, 0x3705, 0x003c); + ov2685_write_register(ViPipe, 0x370a, 0x0021); + ov2685_write_register(ViPipe, 0x370c, 0x0050); + ov2685_write_register(ViPipe, 0x370d, 0x00c0); + ov2685_write_register(ViPipe, 0x3717, 0x0058); + ov2685_write_register(ViPipe, 0x3718, 0x0080); + ov2685_write_register(ViPipe, 0x3720, 0x0000); + ov2685_write_register(ViPipe, 0x3721, 0x0009); + ov2685_write_register(ViPipe, 0x3722, 0x0006); + ov2685_write_register(ViPipe, 0x3723, 0x0059); + ov2685_write_register(ViPipe, 0x3738, 0x0099); + ov2685_write_register(ViPipe, 0x3781, 0x0080); + ov2685_write_register(ViPipe, 0x3784, 0x000c); + ov2685_write_register(ViPipe, 0x3789, 0x0060); + ov2685_write_register(ViPipe, 0x3800, 0x0000); + ov2685_write_register(ViPipe, 0x3801, 0x0000); + ov2685_write_register(ViPipe, 0x3802, 0x0000); + ov2685_write_register(ViPipe, 0x3803, 0x0000); + ov2685_write_register(ViPipe, 0x3804, 0x0006); + ov2685_write_register(ViPipe, 0x3805, 0x004e); + ov2685_write_register(ViPipe, 0x3806, 0x0004); + ov2685_write_register(ViPipe, 0x3807, 0x00be); + ov2685_write_register(ViPipe, 0x3808, 0x0006); + ov2685_write_register(ViPipe, 0x3809, 0x0040); + ov2685_write_register(ViPipe, 0x380a, 0x0004); + ov2685_write_register(ViPipe, 0x380b, 0x00b0); + ov2685_write_register(ViPipe, 0x380c, 0x0006); + ov2685_write_register(ViPipe, 0x380d, 0x00a4); + ov2685_write_register(ViPipe, 0x380e, 0x0005); + ov2685_write_register(ViPipe, 0x380f, 0x000e); + ov2685_write_register(ViPipe, 0x3810, 0x0000); + ov2685_write_register(ViPipe, 0x3811, 0x0008); + ov2685_write_register(ViPipe, 0x3812, 0x0000); + ov2685_write_register(ViPipe, 0x3813, 0x0008); + ov2685_write_register(ViPipe, 0x3814, 0x0011); + ov2685_write_register(ViPipe, 0x3815, 0x0011); + ov2685_write_register(ViPipe, 0x3819, 0x0004); + ov2685_write_register(ViPipe, 0x3820, 0x00c0); + ov2685_write_register(ViPipe, 0x3821, 0x0000); + ov2685_write_register(ViPipe, 0x3a06, 0x0001); + ov2685_write_register(ViPipe, 0x3a07, 0x0084); + ov2685_write_register(ViPipe, 0x3a08, 0x0001); + ov2685_write_register(ViPipe, 0x3a09, 0x0043); + ov2685_write_register(ViPipe, 0x3a0a, 0x0024); + ov2685_write_register(ViPipe, 0x3a0b, 0x0060); + ov2685_write_register(ViPipe, 0x3a0c, 0x0028); + ov2685_write_register(ViPipe, 0x3a0d, 0x0060); + ov2685_write_register(ViPipe, 0x3a0e, 0x0004); + ov2685_write_register(ViPipe, 0x3a0f, 0x008c); + ov2685_write_register(ViPipe, 0x3a10, 0x0005); + ov2685_write_register(ViPipe, 0x3a11, 0x000c); + ov2685_write_register(ViPipe, 0x4000, 0x0081); + ov2685_write_register(ViPipe, 0x4001, 0x0040); + ov2685_write_register(ViPipe, 0x4008, 0x0002); + ov2685_write_register(ViPipe, 0x4009, 0x0009); + ov2685_write_register(ViPipe, 0x4300, 0x0000); + ov2685_write_register(ViPipe, 0x430e, 0x0000); + ov2685_write_register(ViPipe, 0x4602, 0x0002); + ov2685_write_register(ViPipe, 0x481b, 0x0040); + ov2685_write_register(ViPipe, 0x481f, 0x0040); + ov2685_write_register(ViPipe, 0x4837, 0x0030); + ov2685_write_register(ViPipe, 0x5000, 0x001f); + ov2685_write_register(ViPipe, 0x5001, 0x0005); + ov2685_write_register(ViPipe, 0x5002, 0x0030); + ov2685_write_register(ViPipe, 0x5003, 0x0004); + ov2685_write_register(ViPipe, 0x5004, 0x0000); + ov2685_write_register(ViPipe, 0x5005, 0x000c); + ov2685_write_register(ViPipe, 0x0100, 0x0001); + + ov2685_write_register(ViPipe, 0x0000, 0x00); // end flag + + ov2685_default_reg_init(ViPipe); + delay_ms(10); + + printf("ViPipe:%d,===OV2685 1600X1200 30fps 10bit LINEAR Init OK!===\n", ViPipe); +} + + +static __attribute__((unused)) void ov2685_linear_720p30_init(VI_PIPE ViPipe) +{ + ov2685_write_register(ViPipe, 0x0103, 0x0001); + ov2685_write_register(ViPipe, 0x3002, 0x0000); + ov2685_write_register(ViPipe, 0x3016, 0x001c); + ov2685_write_register(ViPipe, 0x3018, 0x0084); + ov2685_write_register(ViPipe, 0x301d, 0x00f0); + ov2685_write_register(ViPipe, 0x3020, 0x0000); + ov2685_write_register(ViPipe, 0x3082, 0x0037); + ov2685_write_register(ViPipe, 0x3083, 0x0003); + ov2685_write_register(ViPipe, 0x3084, 0x0009); + ov2685_write_register(ViPipe, 0x3085, 0x0004); + ov2685_write_register(ViPipe, 0x3086, 0x0000); + ov2685_write_register(ViPipe, 0x3087, 0x0001); + ov2685_write_register(ViPipe, 0x3501, 0x004e); + ov2685_write_register(ViPipe, 0x3502, 0x00e0); + ov2685_write_register(ViPipe, 0x3503, 0x0000); + ov2685_write_register(ViPipe, 0x350b, 0x0036); + ov2685_write_register(ViPipe, 0x3600, 0x00b4); + ov2685_write_register(ViPipe, 0x3603, 0x0035); + ov2685_write_register(ViPipe, 0x3604, 0x0024); + ov2685_write_register(ViPipe, 0x3605, 0x0000); + ov2685_write_register(ViPipe, 0x3620, 0x0024); + ov2685_write_register(ViPipe, 0x3621, 0x0034); + ov2685_write_register(ViPipe, 0x3622, 0x0003); + ov2685_write_register(ViPipe, 0x3628, 0x0010); + ov2685_write_register(ViPipe, 0x3705, 0x003c); + ov2685_write_register(ViPipe, 0x370a, 0x0021); + ov2685_write_register(ViPipe, 0x370c, 0x0050); + ov2685_write_register(ViPipe, 0x370d, 0x00c0); + ov2685_write_register(ViPipe, 0x3717, 0x0058); + ov2685_write_register(ViPipe, 0x3718, 0x0080); + ov2685_write_register(ViPipe, 0x3720, 0x0000); + ov2685_write_register(ViPipe, 0x3721, 0x0009); + ov2685_write_register(ViPipe, 0x3722, 0x0006); + ov2685_write_register(ViPipe, 0x3723, 0x0059); + ov2685_write_register(ViPipe, 0x3738, 0x0099); + ov2685_write_register(ViPipe, 0x3781, 0x0080); + ov2685_write_register(ViPipe, 0x3784, 0x000c); + ov2685_write_register(ViPipe, 0x3789, 0x0060); + ov2685_write_register(ViPipe, 0x3800, 0x0000); + ov2685_write_register(ViPipe, 0x3801, 0x00a0); + ov2685_write_register(ViPipe, 0x3802, 0x0000); + ov2685_write_register(ViPipe, 0x3803, 0x00f0); + ov2685_write_register(ViPipe, 0x3804, 0x0005); + ov2685_write_register(ViPipe, 0x3805, 0x00b4); + ov2685_write_register(ViPipe, 0x3806, 0x0003); + ov2685_write_register(ViPipe, 0x3807, 0x00d4); + ov2685_write_register(ViPipe, 0x3808, 0x0005); + ov2685_write_register(ViPipe, 0x3809, 0x0000); + ov2685_write_register(ViPipe, 0x380a, 0x0002); + ov2685_write_register(ViPipe, 0x380b, 0x00d0); + ov2685_write_register(ViPipe, 0x380c, 0x0006); + ov2685_write_register(ViPipe, 0x380d, 0x00a4); + ov2685_write_register(ViPipe, 0x380e, 0x0005); + ov2685_write_register(ViPipe, 0x380f, 0x000e); + ov2685_write_register(ViPipe, 0x3810, 0x0000); + ov2685_write_register(ViPipe, 0x3811, 0x0008); + ov2685_write_register(ViPipe, 0x3812, 0x0000); + ov2685_write_register(ViPipe, 0x3813, 0x0008); + ov2685_write_register(ViPipe, 0x3814, 0x0011); + ov2685_write_register(ViPipe, 0x3815, 0x0011); + ov2685_write_register(ViPipe, 0x3819, 0x0004); + ov2685_write_register(ViPipe, 0x3820, 0x00c0); + ov2685_write_register(ViPipe, 0x3821, 0x0000); + ov2685_write_register(ViPipe, 0x3a06, 0x0001); + ov2685_write_register(ViPipe, 0x3a07, 0x0084); + ov2685_write_register(ViPipe, 0x3a08, 0x0001); + ov2685_write_register(ViPipe, 0x3a09, 0x0043); + ov2685_write_register(ViPipe, 0x3a0a, 0x0024); + ov2685_write_register(ViPipe, 0x3a0b, 0x0060); + ov2685_write_register(ViPipe, 0x3a0c, 0x0028); + ov2685_write_register(ViPipe, 0x3a0d, 0x0060); + ov2685_write_register(ViPipe, 0x3a0e, 0x0004); + ov2685_write_register(ViPipe, 0x3a0f, 0x008c); + ov2685_write_register(ViPipe, 0x3a10, 0x0005); + ov2685_write_register(ViPipe, 0x3a11, 0x000c); + ov2685_write_register(ViPipe, 0x4000, 0x0081); + ov2685_write_register(ViPipe, 0x4001, 0x0040); + ov2685_write_register(ViPipe, 0x4008, 0x0002); + ov2685_write_register(ViPipe, 0x4009, 0x0009); + ov2685_write_register(ViPipe, 0x4300, 0x0000); + ov2685_write_register(ViPipe, 0x430e, 0x0000); + ov2685_write_register(ViPipe, 0x4602, 0x0002); + ov2685_write_register(ViPipe, 0x481b, 0x0040); + ov2685_write_register(ViPipe, 0x481f, 0x0040); + ov2685_write_register(ViPipe, 0x4837, 0x0030); + ov2685_write_register(ViPipe, 0x5000, 0x001f); + ov2685_write_register(ViPipe, 0x5001, 0x0005); + ov2685_write_register(ViPipe, 0x5002, 0x0030); + ov2685_write_register(ViPipe, 0x5003, 0x0004); + ov2685_write_register(ViPipe, 0x5004, 0x0000); + ov2685_write_register(ViPipe, 0x5005, 0x000c); + ov2685_write_register(ViPipe, 0x0100, 0x0001); + + ov2685_write_register(ViPipe, 0x0000, 0x00); // end flag + + ov2685_default_reg_init(ViPipe); + delay_ms(10); + + printf("ViPipe:%d,===OV2685 1280x720 30fps 10bit LINEAR Init OK!===\n", ViPipe); +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov4689/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov4689/Makefile new file mode 100644 index 00000000..b492c96f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov4689/ov4689_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov4689/ov4689_cmos.c new file mode 100644 index 00000000..f3b0f577 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov4689/ov4689_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov4689/ov4689_cmos_ex.h new file mode 100644 index 00000000..cbbf6dc1 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov4689/ov4689_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov4689/ov4689_cmos_param.h new file mode 100644 index 00000000..d8c6c1bd --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov4689/ov4689_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov4689/ov4689_sensor_ctl.c new file mode 100644 index 00000000..ca947913 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov5647/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov5647/Makefile new file mode 100644 index 00000000..7ae38111 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov5647/Makefile @@ -0,0 +1,37 @@ +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_ov5647.a +TARGET_SO = $(MW_LIB)/libsns_ov5647.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov5647/ov5647_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov5647/ov5647_cmos.c new file mode 100644 index 00000000..b7cc52d2 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov5647/ov5647_cmos.c @@ -0,0 +1,893 @@ +#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 "ov5647_cmos_ex.h" +#include "ov5647_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 OV5647_ID 0x5647 +#define OV5647_I2C_ADDR_1 0x36 +#define OV5647_I2C_ADDR_2 0x10 +#define OV5647_I2C_ADDR_IS_VALID(addr) \ + ((addr) == OV5647_I2C_ADDR_1 || (addr) == OV5647_I2C_ADDR_2) +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastOv5647[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define OV5647_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastOv5647[dev]) +#define OV5647_SENSOR_SET_CTX(dev, pstCtx) (g_pastOv5647[dev] = pstCtx) +#define OV5647_SENSOR_RESET_CTX(dev) (g_pastOv5647[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunOv5647_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Ov5647_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Ov5647_UseHwSync[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeOv5647_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); +/*****Ov5647 Lines Range*****/ +#define OV5647_FULL_LINES_MAX (0xFFFF) + +/*****Ov5647 Register Address*****/ +#define OV5647_HOLD_3208 0x3208 +#define OV5647_HOLD_320B 0x320B +#define OV5647_EXP1_ADDR 0x3500 +#define OV5647_AGAIN1_ADDR 0x350A +#define OV5647_VTS_ADDR 0x380E + +#define OV5647_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 OV5647_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + OV5647_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astOv5647_mode[pstSnsState->u8ImgMode]; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = OV5647_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; + /* OV sensor cannot update new setting before the old setting takes effect */ + pstAeSnsDft->u8AERunInterval = 1; + 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); + OV5647_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astOv5647_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astOv5647_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astOv5647_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case OV5647_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 > OV5647_FULL_LINES_MAX) ? OV5647_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; + + OV5647_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 & 0xFF0) >> 4); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_2].u32Data = ((u32TmpIntTime & 0x0F) << 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[7] = { + { + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 3968, + .idxBase = 16, + .regGain = 0x00, + .regGainFineBase = 0x20, + .regGainFineStep = 2, + }, + { + .gainMax = 7936, + .idxBase = 32, + .regGain = 0x00, + .regGainFineBase = 0x40, + .regGainFineStep = 4, + }, + { + .gainMax = 15872, + .idxBase = 48, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 8, + }, + { + .gainMax = 31744, + .idxBase = 64, + .regGain = 0x01, + .regGainFineBase = 0x00, + .regGainFineStep = 16, + }, + { + .gainMax = 47104, + .idxBase = 80, + .regGain = 0x02, + .regGainFineBase = 0x00, + .regGainFineStep = 32, + }, + { + .gainMax = 63488, + .idxBase = 88, + .regGain = 0x03, + .regGainFineBase = 0x00, + .regGainFineStep = 32, + }, + +}; + +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, + 8192, 8704, 9216, 9728, 10240, 10752, 11264, 11776, 12288, 12800, 13312, 13824, 14336, 14848, 15360, 15872, + 16384, 17408, 18432, 19456, 20480, 21504, 22528, 23552, 24576, 25600, 26624, 27648, 28672, 29696, 30720, 31744, + 32768, 34816, 36864, 38912, 40960, 43008, 45056, 47104, 49152, 51200, 53248, 55296, 57344, 59392, 61440, 63488 +}; + +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; + + OV5647_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 = info->regGain & 0xFF; + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_1].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_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; + + 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 OV5647_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV5647_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astOv5647_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; + + OV5647_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = OV5647_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOv5647_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); + OV5647_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_aunOv5647_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 = ov5647_i2c_addr; + pstI2c_data[i].u32AddrByteNum = ov5647_addr_byte; + pstI2c_data[i].u32DataByteNum = ov5647_data_byte; + } + + switch (pstSnsState->enWDRMode) { + default: + pstI2c_data[LINEAR_EXP_0].u32RegAddr = OV5647_EXP1_ADDR; + pstI2c_data[LINEAR_EXP_1].u32RegAddr = OV5647_EXP1_ADDR + 1; + pstI2c_data[LINEAR_EXP_2].u32RegAddr = OV5647_EXP1_ADDR + 2; + pstI2c_data[LINEAR_AGAIN_0].u32RegAddr = OV5647_AGAIN1_ADDR; + pstI2c_data[LINEAR_AGAIN_1].u32RegAddr = OV5647_AGAIN1_ADDR + 1; + pstI2c_data[LINEAR_VTS_0].u32RegAddr = OV5647_VTS_ADDR; + pstI2c_data[LINEAR_VTS_1].u32RegAddr = OV5647_VTS_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); + } + + 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); + OV5647_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 (OV5647_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = OV5647_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; + + OV5647_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeOv5647_MirrorFip[ViPipe] != eSnsMirrorFlip) { + ov5647_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeOv5647_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + OV5647_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = OV5647_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astOv5647_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_astOv5647_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_astOv5647_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; + + OV5647_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &ov5647_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astOv5647_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astOv5647_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 = &ov5647_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 = ov5647_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = ov5647_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 (OV5647_I2C_ADDR_IS_VALID(s32I2cAddr)) + ov5647_i2c_addr = s32I2cAddr; +} + +static CVI_S32 ov5647_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunOv5647_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OV5647_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)); + + OV5647_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + OV5647_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + OV5647_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 = OV5647_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, OV5647_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, OV5647_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, OV5647_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_au16Ov5647_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Ov5647_UseHwSync[ViPipe] = pstInitAttr->u16UseHwSync; + + return CVI_SUCCESS; +} +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return ov5647_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsOv5647_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = ov5647_standby, + .pfnRestart = ov5647_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = ov5647_write_register, + .pfnReadReg = ov5647_read_register, + .pfnSetBusInfo = ov5647_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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov5647/ov5647_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov5647/ov5647_cmos_ex.h new file mode 100644 index 00000000..99769576 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov5647/ov5647_cmos_ex.h @@ -0,0 +1,89 @@ +#ifndef __OV5647_CMOS_EX_H_ +#define __OV5647_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 ov5647_linear_regs_e { + LINEAR_EXP_0, + LINEAR_EXP_1, + LINEAR_EXP_2, + LINEAR_AGAIN_0, + LINEAR_AGAIN_1, + LINEAR_VTS_0, + LINEAR_VTS_1, + LINEAR_REGS_NUM +}; + +typedef enum _OV5647_MODE_E { + OV5647_MODE_1920X1080P30 = 0, + OV5647_MODE_LINEAR_NUM, + OV5647_MODE_NUM +} OV5647_MODE_E; + +typedef struct _OV5647_STATE_S { + CVI_U32 u32Sexp_MAX; +} OV5647_STATE_S; + +typedef struct _OV5647_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]; +} OV5647_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastOv5647[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunOv5647_BusInfo[]; +extern CVI_U16 g_au16Ov5647_GainMode[]; +extern CVI_U16 g_au16Ov5647_UseHwSync[VI_MAX_PIPE_NUM]; +extern CVI_U8 ov5647_i2c_addr; +extern const CVI_U32 ov5647_addr_byte; +extern const CVI_U32 ov5647_data_byte; +extern void ov5647_init(VI_PIPE ViPipe); +extern void ov5647_exit(VI_PIPE ViPipe); +extern void ov5647_standby(VI_PIPE ViPipe); +extern void ov5647_restart(VI_PIPE ViPipe); +extern int ov5647_write_register(VI_PIPE ViPipe, int addr, int data); +extern int ov5647_read_register(VI_PIPE ViPipe, int addr); +extern void ov5647_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int ov5647_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __OV5647_CMOS_EX_H_ */ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov5647/ov5647_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov5647/ov5647_cmos_param.h new file mode 100644 index 00000000..30aee31e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov5647/ov5647_cmos_param.h @@ -0,0 +1,129 @@ +#ifndef __OV5647_CMOS_PARAM_H_ +#define __OV5647_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 "ov5647_cmos_ex.h" + +static const OV5647_MODE_S g_astOv5647_mode[OV5647_MODE_NUM] = { + [OV5647_MODE_1920X1080P30] = { + .name = "1920x1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 2592, + .u32Height = 1944, + }, + }, + + .f32MaxFps = 30, + .f32MinFps = 0.711, /* 0x4e2 * 30 / 0xFFFF */ + .u32HtsDef = 2416, + .u32VtsDef = 1104, + .stExp[0] = { + .u16Min = 4, + .u16Max = 1104 - 4, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 63448, + .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 = {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 ov5647_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, + .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 /* __OV5647_CMOS_PARAM_H_ */ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov5647/ov5647_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov5647/ov5647_sensor_ctl.c new file mode 100644 index 00000000..8e2c2892 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov5647/ov5647_sensor_ctl.c @@ -0,0 +1,347 @@ +#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 "ov5647_cmos_ex.h" + +static void ov5647_linear_1080p30_init(VI_PIPE ViPipe); + +CVI_U8 ov5647_i2c_addr = 0x36; /* I2C Address of OV5647 */ +const CVI_U32 ov5647_addr_byte = 2; +const CVI_U32 ov5647_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int ov5647_i2c_init(VI_PIPE ViPipe) +{ + + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunOv5647_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, ov5647_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 ov5647_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 ov5647_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 (ov5647_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, ov5647_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, ov5647_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (ov5647_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 ov5647_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 (ov5647_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (ov5647_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, ov5647_addr_byte + ov5647_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 ov5647_standby(VI_PIPE ViPipe) +{ + ov5647_write_register(ViPipe, 0x0100, 0x00); /* STANDBY */ +} + +void ov5647_restart(VI_PIPE ViPipe) +{ + ov5647_write_register(ViPipe, 0x0100, 0x01); /* standby */ +} + +void ov5647_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + CVI_U32 start = 1; + CVI_U32 end = g_pastOv5647[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum - 3; + + for (i = start; i < end; i++) { + ov5647_write_register(ViPipe, + g_pastOv5647[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastOv5647[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define OV5647_FLIP 0x3820 +#define OV5647_MIRROR 0x3821 +void ov5647_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 flip, mirror; + + flip = ov5647_read_register(ViPipe, OV5647_FLIP); + mirror = ov5647_read_register(ViPipe, OV5647_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; + } + + ov5647_write_register(ViPipe, OV5647_FLIP, flip); + ov5647_write_register(ViPipe, OV5647_MIRROR, mirror); +} + +#define OV5647_CHIP_ID_ADDR_H 0x300A +#define OV5647_CHIP_ID_ADDR_L 0x300B +#define OV5647_CHIP_ID 0x5647 + +int ov5647_probe(VI_PIPE ViPipe) +{ + int nVal, nVal2; + + usleep(1000); + if (ov5647_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = ov5647_read_register(ViPipe, OV5647_CHIP_ID_ADDR_H); + nVal2 = ov5647_read_register(ViPipe, OV5647_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)) != OV5647_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + return CVI_SUCCESS; +} + +void ov5647_init(VI_PIPE ViPipe) +{ + ov5647_i2c_init(ViPipe); + + delay_ms(10); + + ov5647_linear_1080p30_init(ViPipe); + + g_pastOv5647[ViPipe]->bInit = CVI_TRUE; +} + +void ov5647_exit(VI_PIPE ViPipe) +{ + ov5647_i2c_exit(ViPipe); +} + +/* 1080P30 */ +static void ov5647_linear_1080p30_init(VI_PIPE ViPipe) +{ + ov5647_write_register(ViPipe, 0x0100, 0x00); + ov5647_write_register(ViPipe, 0x0103, 0x01); + ov5647_write_register(ViPipe, 0x3035, 0x11); + ov5647_write_register(ViPipe, 0x3036, 0x64); + ov5647_write_register(ViPipe, 0x303c, 0x11); + ov5647_write_register(ViPipe, 0x3821, 0x00); + ov5647_write_register(ViPipe, 0x3820, 0x00); + ov5647_write_register(ViPipe, 0x370c, 0x0f); + ov5647_write_register(ViPipe, 0x3612, 0x5b); + ov5647_write_register(ViPipe, 0x3618, 0x04); + ov5647_write_register(ViPipe, 0x5000, 0x06); + ov5647_write_register(ViPipe, 0x5002, 0x40); + ov5647_write_register(ViPipe, 0x5003, 0x08); + ov5647_write_register(ViPipe, 0x5a00, 0x08); + ov5647_write_register(ViPipe, 0x3000, 0xff); + ov5647_write_register(ViPipe, 0x3001, 0xff); + ov5647_write_register(ViPipe, 0x3002, 0xff); + ov5647_write_register(ViPipe, 0x301d, 0xf0); + ov5647_write_register(ViPipe, 0x3503, 0x07); + ov5647_write_register(ViPipe, 0x3a18, 0x00); + ov5647_write_register(ViPipe, 0x3a19, 0xf8); + ov5647_write_register(ViPipe, 0x3c01, 0x80); + ov5647_write_register(ViPipe, 0x3b07, 0x0c); + ov5647_write_register(ViPipe, 0x380c, 0x09); + ov5647_write_register(ViPipe, 0x380d, 0x70); + ov5647_write_register(ViPipe, 0x380e, 0x04); + ov5647_write_register(ViPipe, 0x380f, 0x50); + ov5647_write_register(ViPipe, 0x3814, 0x11); + ov5647_write_register(ViPipe, 0x3815, 0x11); + ov5647_write_register(ViPipe, 0x3708, 0x64); + ov5647_write_register(ViPipe, 0x3709, 0x12); + ov5647_write_register(ViPipe, 0x3808, 0x07); + ov5647_write_register(ViPipe, 0x3809, 0x80); + ov5647_write_register(ViPipe, 0x380a, 0x04); + ov5647_write_register(ViPipe, 0x380b, 0x38); + ov5647_write_register(ViPipe, 0x3800, 0x01); + ov5647_write_register(ViPipe, 0x3801, 0x5c); + ov5647_write_register(ViPipe, 0x3802, 0x01); + ov5647_write_register(ViPipe, 0x3803, 0xb2); + ov5647_write_register(ViPipe, 0x3804, 0x08); + ov5647_write_register(ViPipe, 0x3805, 0xe3); + ov5647_write_register(ViPipe, 0x3806, 0x05); + ov5647_write_register(ViPipe, 0x3807, 0xf1); + ov5647_write_register(ViPipe, 0x3630, 0x2e); + ov5647_write_register(ViPipe, 0x3632, 0xe2); + ov5647_write_register(ViPipe, 0x3633, 0x23); + ov5647_write_register(ViPipe, 0x3634, 0x44); + ov5647_write_register(ViPipe, 0x3620, 0x64); + ov5647_write_register(ViPipe, 0x3621, 0xe0); + ov5647_write_register(ViPipe, 0x3600, 0x37); + ov5647_write_register(ViPipe, 0x3704, 0xa0); + ov5647_write_register(ViPipe, 0x3703, 0x5a); + ov5647_write_register(ViPipe, 0x3715, 0x78); + ov5647_write_register(ViPipe, 0x3717, 0x01); + ov5647_write_register(ViPipe, 0x3731, 0x02); + ov5647_write_register(ViPipe, 0x370b, 0x60); + ov5647_write_register(ViPipe, 0x3705, 0x1a); + ov5647_write_register(ViPipe, 0x3f05, 0x02); + ov5647_write_register(ViPipe, 0x3f06, 0x10); + ov5647_write_register(ViPipe, 0x3f01, 0x0a); + ov5647_write_register(ViPipe, 0x3a08, 0x01); + ov5647_write_register(ViPipe, 0x3a09, 0x4b); + ov5647_write_register(ViPipe, 0x3a0a, 0x01); + ov5647_write_register(ViPipe, 0x3a0b, 0x13); + ov5647_write_register(ViPipe, 0x3a0d, 0x04); + ov5647_write_register(ViPipe, 0x3a0e, 0x03); + ov5647_write_register(ViPipe, 0x3a0f, 0x58); + ov5647_write_register(ViPipe, 0x3a10, 0x50); + ov5647_write_register(ViPipe, 0x3a1b, 0x58); + ov5647_write_register(ViPipe, 0x3a1e, 0x50); + ov5647_write_register(ViPipe, 0x3a11, 0x60); + ov5647_write_register(ViPipe, 0x3a1f, 0x28); + ov5647_write_register(ViPipe, 0x4001, 0x02); + ov5647_write_register(ViPipe, 0x4004, 0x04); + ov5647_write_register(ViPipe, 0x4000, 0x09); + ov5647_write_register(ViPipe, 0x4050, 0x6e); + ov5647_write_register(ViPipe, 0x4051, 0x8f); + ov5647_write_register(ViPipe, 0x0100, 0x01); + ov5647_write_register(ViPipe, 0x3000, 0x00); + ov5647_write_register(ViPipe, 0x3001, 0x00); + ov5647_write_register(ViPipe, 0x3002, 0x00); + ov5647_write_register(ViPipe, 0x3017, 0xe0); + ov5647_write_register(ViPipe, 0x301c, 0xfc); + ov5647_write_register(ViPipe, 0x3636, 0x06); + ov5647_write_register(ViPipe, 0x3016, 0x08); + ov5647_write_register(ViPipe, 0x3827, 0xec); + ov5647_write_register(ViPipe, 0x3018, 0x44); + ov5647_write_register(ViPipe, 0x3035, 0x21); + ov5647_write_register(ViPipe, 0x3106, 0xf5); + ov5647_write_register(ViPipe, 0x3034, 0x1a); + ov5647_write_register(ViPipe, 0x301c, 0xf8); + + ov5647_default_reg_init(ViPipe); + + delay_ms(100); + + printf("ViPipe:%d,===OV5647 1080P 30fps 10bit LINE Init OK!\n", ViPipe); +} + + + + + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov6211/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov6211/Makefile new file mode 100644 index 00000000..ec5cc8cb --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov6211/ov6211_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov6211/ov6211_cmos.c new file mode 100644 index 00000000..e057796a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov6211/ov6211_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov6211/ov6211_cmos_ex.h new file mode 100644 index 00000000..d8427c34 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov6211/ov6211_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov6211/ov6211_cmos_param.h new file mode 100644 index 00000000..1274eb2a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov6211/ov6211_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov6211/ov6211_sensor_ctl.c new file mode 100644 index 00000000..56cef42f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov7251/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov7251/Makefile new file mode 100644 index 00000000..880ea850 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov7251/ov7251_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov7251/ov7251_cmos.c new file mode 100644 index 00000000..bdf88a6a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov7251/ov7251_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov7251/ov7251_cmos_ex.h new file mode 100644 index 00000000..339ec679 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov7251/ov7251_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov7251/ov7251_cmos_param.h new file mode 100644 index 00000000..adf3415d --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov7251/ov7251_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/ov_ov7251/ov7251_sensor_ctl.c new file mode 100644 index 00000000..38d3518b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2020/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2020/Makefile new file mode 100644 index 00000000..7ebc9b71 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2020/pr2020_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2020/pr2020_cmos.c new file mode 100644 index 00000000..37d5fadb --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= VI_MAX_DEV_NUM) + 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2020/pr2020_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2020/pr2020_cmos_ex.h new file mode 100644 index 00000000..7bd2db22 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2020/pr2020_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2020/pr2020_cmos_param.h new file mode 100644 index 00000000..309f9260 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2020/pr2020_sensor_ctrl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2020/pr2020_sensor_ctrl.c new file mode 100644 index 00000000..d50158fd --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2100/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2100/Makefile new file mode 100644 index 00000000..4b21c77e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2100/pr2100_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2100/pr2100_cmos.c new file mode 100644 index 00000000..9c88e63e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2100/pr2100_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2100/pr2100_cmos_ex.h new file mode 100644 index 00000000..3bb5e749 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2100/pr2100_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2100/pr2100_cmos_param.h new file mode 100644 index 00000000..c0413d8a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2100/pr2100_sensor_ctrl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/pixelplus_pr2100/pr2100_sensor_ctrl.c new file mode 100644 index 00000000..77c52ab7 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs/Makefile new file mode 100644 index 00000000..b1901ad9 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs/sc035gs_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs/sc035gs_cmos.c new file mode 100644 index 00000000..23eac27b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs/sc035gs_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs/sc035gs_cmos_ex.h new file mode 100644 index 00000000..1f727fd1 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs/sc035gs_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs/sc035gs_cmos_param.h new file mode 100644 index 00000000..70f3f7b7 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs/sc035gs_cmos_param.h @@ -0,0 +1,127 @@ +#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 = 1136, // 0x320c/d 036b=878 0470=1136 + .u32VtsDef = 528, // 0x320e/f 02ab=683 0210=528 + .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_600M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {4, 3, 2, -1, -1}, + .pn_swap = {0, 0, 0, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 8, + }, + }, + .mclk = { + .cam = 0, + // .freq = CAMPLL_FREQ_37P125M, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC035GS_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs/sc035gs_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs/sc035gs_sensor_ctl.c new file mode 100644 index 00000000..c362404c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs/sc035gs_sensor_ctl.c @@ -0,0 +1,345 @@ +#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) +{ + printf("########### PinMux #######################################################################\n"); + system("devmem 0x0300116C 32 0x3"); + system("devmem 0x03001170 32 0x3"); + system("devmem 0x03001174 32 0x3"); + system("devmem 0x03001178 32 0x3"); + system("devmem 0x0300117C 32 0x3"); + system("devmem 0x03001180 32 0x3"); + system("devmem 0x03001184 32 0x3"); + system("devmem 0x03001188 32 0x3"); + system("devmem 0x0300118C 32 0x5"); + system("devmem 0x03001190 32 0x3"); + printf("########### PinMux End #######################################################################\n"); + + //============================================================================================================================================= + // MTK6739 - 60FPS + sc035gs_write_register(ViPipe, 0x0103, 0x01); + delay_ms(33); + sc035gs_write_register(ViPipe, 0x0100, 0x00); + 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, 0xfc); + sc035gs_write_register(ViPipe, 0x301c, 0x78); + sc035gs_write_register(ViPipe, 0x301f, 0xa2); + sc035gs_write_register(ViPipe, 0x3031, 0x0a); + sc035gs_write_register(ViPipe, 0x3037, 0x20); + sc035gs_write_register(ViPipe, 0x303f, 0x01); + + // MTK6739 - 60FPS + sc035gs_write_register(ViPipe, 0x320c, 0x03); // 852 + sc035gs_write_register(ViPipe, 0x320d, 0x54); + sc035gs_write_register(ViPipe, 0x320e, 0x02); // 2112 + sc035gs_write_register(ViPipe, 0x320f, 0x0e); + sc035gs_write_register(ViPipe, 0x3252, 0x02); + sc035gs_write_register(ViPipe, 0x3253, 0x08); + sc035gs_write_register(ViPipe, 0x3217, 0x00); + sc035gs_write_register(ViPipe, 0x3218, 0x00); + sc035gs_write_register(ViPipe, 0x3220, 0x10); + sc035gs_write_register(ViPipe, 0x3223, 0x48); + sc035gs_write_register(ViPipe, 0x3226, 0x74); + sc035gs_write_register(ViPipe, 0x3227, 0x07); + sc035gs_write_register(ViPipe, 0x323b, 0x00); + sc035gs_write_register(ViPipe, 0x3250, 0xf0); + 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, 0x3305, 0x00); + sc035gs_write_register(ViPipe, 0x3306, 0x60); + sc035gs_write_register(ViPipe, 0x3309, 0x50); + sc035gs_write_register(ViPipe, 0x330a, 0x00); + sc035gs_write_register(ViPipe, 0x330b, 0xc0); + sc035gs_write_register(ViPipe, 0x330c, 0x18); + sc035gs_write_register(ViPipe, 0x330f, 0x40); + sc035gs_write_register(ViPipe, 0x3310, 0x10); + sc035gs_write_register(ViPipe, 0x3314, 0x1e); + sc035gs_write_register(ViPipe, 0x3315, 0x30); + sc035gs_write_register(ViPipe, 0x3316, 0x68); + sc035gs_write_register(ViPipe, 0x3317, 0x1b); + sc035gs_write_register(ViPipe, 0x3329, 0x5c); + sc035gs_write_register(ViPipe, 0x332d, 0x5c); + sc035gs_write_register(ViPipe, 0x332f, 0x60); + sc035gs_write_register(ViPipe, 0x3335, 0x64); + sc035gs_write_register(ViPipe, 0x3344, 0x64); + 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, 0x39); + sc035gs_write_register(ViPipe, 0x3389, 0x01); + sc035gs_write_register(ViPipe, 0x33b1, 0x03); + sc035gs_write_register(ViPipe, 0x33b2, 0x06); + sc035gs_write_register(ViPipe, 0x33bd, 0xe0); + sc035gs_write_register(ViPipe, 0x33bf, 0x10); + sc035gs_write_register(ViPipe, 0x3621, 0xa4); + sc035gs_write_register(ViPipe, 0x3622, 0x05); + sc035gs_write_register(ViPipe, 0x3624, 0x47); + sc035gs_write_register(ViPipe, 0x3630, 0x4a); + sc035gs_write_register(ViPipe, 0x3631, 0x58); + sc035gs_write_register(ViPipe, 0x3633, 0x52); + sc035gs_write_register(ViPipe, 0x3635, 0x03); + sc035gs_write_register(ViPipe, 0x3636, 0x25); + sc035gs_write_register(ViPipe, 0x3637, 0x8a); + 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, 0x86); + 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, 0x36e9, 0x80); + sc035gs_write_register(ViPipe, 0x36ea, 0x37); + sc035gs_write_register(ViPipe, 0x36eb, 0x0e); + sc035gs_write_register(ViPipe, 0x36ec, 0x1e); + sc035gs_write_register(ViPipe, 0x36ed, 0x23); + sc035gs_write_register(ViPipe, 0x36f9, 0x80); + sc035gs_write_register(ViPipe, 0x36fa, 0x37); + sc035gs_write_register(ViPipe, 0x36fb, 0x00); + sc035gs_write_register(ViPipe, 0x36fc, 0x02); + sc035gs_write_register(ViPipe, 0x36fd, 0x03); + sc035gs_write_register(ViPipe, 0x3908, 0x91); + sc035gs_write_register(ViPipe, 0x391b, 0x81); + sc035gs_write_register(ViPipe, 0x3d08, 0x01); + sc035gs_write_register(ViPipe, 0x3e01, 0x83); + sc035gs_write_register(ViPipe, 0x3e02, 0x80); + sc035gs_write_register(ViPipe, 0x3e03, 0x2b); + sc035gs_write_register(ViPipe, 0x3e06, 0x0c); + sc035gs_write_register(ViPipe, 0x3f04, 0x03); + sc035gs_write_register(ViPipe, 0x3f05, 0x34); + sc035gs_write_register(ViPipe, 0x4500, 0x59); + sc035gs_write_register(ViPipe, 0x4501, 0xc4); + sc035gs_write_register(ViPipe, 0x4603, 0x00); + sc035gs_write_register(ViPipe, 0x4800, 0x64); + sc035gs_write_register(ViPipe, 0x4809, 0x01); + sc035gs_write_register(ViPipe, 0x4810, 0x00); + sc035gs_write_register(ViPipe, 0x4811, 0x01); + sc035gs_write_register(ViPipe, 0x4837, 0x26); + sc035gs_write_register(ViPipe, 0x5011, 0x00); + sc035gs_write_register(ViPipe, 0x5988, 0x02); + sc035gs_write_register(ViPipe, 0x598e, 0x03); + sc035gs_write_register(ViPipe, 0x598f, 0x01); + sc035gs_write_register(ViPipe, 0x36e9, 0x24); + sc035gs_write_register(ViPipe, 0x36f9, 0x20); + sc035gs_write_register(ViPipe, 0x0100, 0x01); + delay_ms(20); + sc035gs_write_register(ViPipe, 0x4418, 0x0a); + sc035gs_write_register(ViPipe, 0x363d, 0x10); + sc035gs_write_register(ViPipe, 0x4419, 0x80); + + + printf("ViPipe:%d,===SC035GS 480P 120fps 12bit LINE Init OK!===\n", ViPipe); +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs_1L/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs_1L/Makefile new file mode 100644 index 00000000..64cc1ef8 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs_1L/sc035gs_1L_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs_1L/sc035gs_1L_cmos.c new file mode 100644 index 00000000..6e7fa9a4 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs_1L/sc035gs_1L_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs_1L/sc035gs_1L_cmos_ex.h new file mode 100644 index 00000000..dfa0a52e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs_1L/sc035gs_1L_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs_1L/sc035gs_1L_cmos_param.h new file mode 100644 index 00000000..1df5b1eb --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs_1L/sc035gs_1L_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035gs_1L/sc035gs_1L_sensor_ctl.c new file mode 100644 index 00000000..ff33222e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs/Makefile new file mode 100644 index 00000000..58ef7260 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs/sc035hgs_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs/sc035hgs_cmos.c new file mode 100644 index 00000000..a11b042c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs/sc035hgs_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs/sc035hgs_cmos_ex.h new file mode 100644 index 00000000..2e9b6e4f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs/sc035hgs_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs/sc035hgs_cmos_param.h new file mode 100644 index 00000000..8331c5ff --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs/sc035hgs_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs/sc035hgs_sensor_ctl.c new file mode 100644 index 00000000..eaad111e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs_1L/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs_1L/Makefile new file mode 100644 index 00000000..9f5e1556 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs_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_sc035hgs_1L.a +TARGET_SO = $(MW_LIB)/libsns_sc035hgs_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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs_1L/sc035hgs_1L_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs_1L/sc035hgs_1L_cmos.c new file mode 100644 index 00000000..4a4e7201 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs_1L/sc035hgs_1L_cmos.c @@ -0,0 +1,987 @@ +#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_1L_cmos_ex.h" +#include "sc035hgs_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 SC035HGS_1L_ID 35 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC035HGS_1L[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC035HGS_1L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC035HGS_1L[dev]) +#define SC035HGS_1L_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC035HGS_1L[dev] = pstCtx) +#define SC035HGS_1L_SENSOR_RESET_CTX(dev) (g_pastSC035HGS_1L[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC035HGS_1L_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC035HGS_1L_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC035HGS_1L_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc035hgs_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); +/*****SC035HGS_1L Lines Range*****/ +#define SC035HGS_1L_FULL_LINES_MAX (0xFFFF) + +/*****SC035HGS_1L Register Address*****/ +#define SC035HGS_1L_EXP_H_ADDR (0x3e01) +#define SC035HGS_1L_EXP_L_ADDR (0x3e02) + +#define SC035HGS_1L_AGAIN_H_ADDR (0x3e08) +#define SC035HGS_1L_AGAIN_L_ADDR (0x3e09) + +#define SC035HGS_1L_DGAIN_H_ADDR (0x3e06) +#define SC035HGS_1L_DGAIN_L_ADDR (0x3e07) + +#define SC035HGS_1L_VMAX_H_ADDR (0x320e) +#define SC035HGS_1L_VMAX_L_ADDR (0x320f) + +#define SC035HGS_1L_GAIN_MAGIC_0_ADDR (0x3314) +#define SC035HGS_1L_GAIN_MAGIC_1_ADDR (0x3317) +#define SC035HGS_1L_GAIN_MAGIC_2_ADDR (0x3631) +#define SC035HGS_1L_GAIN_MAGIC_3_ADDR (0x3630) + +#define SC035HGS_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 SC035HGS_1L_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC035HGS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC035HGS_1L_mode[pstSnsState->u8ImgMode]; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC035HGS_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; + + 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); + SC035HGS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC035HGS_1L_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC035HGS_1L_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC035HGS_1L_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC035HGS_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 > SC035HGS_1L_FULL_LINES_MAX) ? SC035HGS_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; + + SC035HGS_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; + +} + +struct gain_tbl_info_s { + CVI_U32 gainMax; + CVI_U32 idxBase; + CVI_U8 regGain; + CVI_U8 regGainFineBase; + CVI_U8 regGainFineStep; +}; + +static struct gain_tbl_info_s AgainInfo[4] = { + { + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 3968, + .idxBase = 16, + .regGain = 0x01, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, +/* vendor suggest the maximum again shall not be larger than 4X*/ + { + .gainMax = 7936, + .idxBase = 32, + .regGain = 0x03, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, + { + .gainMax = 15872, + .idxBase = 48, + .regGain = 0x07, + .regGainFineBase = 0x10, + .regGainFineStep = 1, + }, +}; + +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, 8192, 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 struct gain_tbl_info_s DgainInfo[3] = { + { + .gainMax = 1984, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 8, + }, + { + .gainMax = 3968, + .idxBase = 16, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 8, + }, + { + .gainMax = 7936, + .idxBase = 32, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 8, + }, +}; + +static CVI_U32 Dgain_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 +}; + +static const CVI_U32 dgain_table_size = ARRAY_SIZE(Dgain_table); + +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; + + SC035HGS_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; + } + + /* gain logic setting. */ + if (u32Again < 16) {//gain<2 + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_0_ADDR].u32Data = 0x6b; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_1_ADDR].u32Data = 0x14; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_2_ADDR].u32Data = 0x58; + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_3_ADDR].u32Data = 0x4a; + } else if (u32Again < 32) {//[gain<4] + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_0_ADDR].u32Data = 0x4f; + 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 = 0x4c; + } else { + pstSnsRegsInfo->astI2cData[LINEAR_GAIN_MAGIC_0_ADDR].u32Data = 0x74; + 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 = 0x4c; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H_ADDR].u32Data = (info->regGain << 2) | 0x3; + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L_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 = 0x0C | info->regGain; + 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_1L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035HGS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC035HGS_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; + + SC035HGS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC035HGS_1L_MODE_640X480P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC035HGS_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); + SC035HGS_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_aunSC035HGS_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 = sc035hgs_1L_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc035hgs_1L_addr_byte; + pstI2c_data[i].u32DataByteNum = sc035hgs_1L_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC035HGS_1L_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC035HGS_1L_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H_ADDR].u32RegAddr = SC035HGS_1L_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L_ADDR].u32RegAddr = SC035HGS_1L_AGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC035HGS_1L_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC035HGS_1L_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC035HGS_1L_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC035HGS_1L_VMAX_L_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_0_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_0_ADDR].u32RegAddr = SC035HGS_1L_GAIN_MAGIC_0_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_1_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_1_ADDR].u32RegAddr = SC035HGS_1L_GAIN_MAGIC_1_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_2_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_2_ADDR].u32RegAddr = SC035HGS_1L_GAIN_MAGIC_2_ADDR; + pstI2c_data[LINEAR_GAIN_MAGIC_3_ADDR].bUpdate = CVI_FALSE; + pstI2c_data[LINEAR_GAIN_MAGIC_3_ADDR].u32RegAddr = SC035HGS_1L_GAIN_MAGIC_3_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); + SC035HGS_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 (SC035HGS_1L_RES_IS_480P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC035HGS_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_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC035HGS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeSc035hgs_MirrorFip[ViPipe] != eSnsMirrorFlip) { + sc035hgs_1L_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeSc035hgs_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC035HGS_1L_MODE_S *pstMode = CVI_NULL; + + SC035HGS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC035HGS_1L_MODE_640X480P120; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC035HGS_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; + + SC035HGS_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc035hgs_1L_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC035HGS_1L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC035HGS_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 = &sc035hgs_1L_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 = sc035hgs_1L_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc035hgs_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 sc035hgs_1L_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC035HGS_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; + + SC035HGS_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)); + + SC035HGS_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; + + SC035HGS_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC035HGS_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 = SC035HGS_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, SC035HGS_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, SC035HGS_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, SC035HGS_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_au16SC035HGS_1L_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC035HGS_1L_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC035HGS_1L_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc035hgs_1L_standby, + .pfnRestart = sc035hgs_1L_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = sc035hgs_1L_write_register, + .pfnReadReg = sc035hgs_1L_read_register, + .pfnSetBusInfo = sc035hgs_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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs_1L/sc035hgs_1L_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs_1L/sc035hgs_1L_cmos_ex.h new file mode 100644 index 00000000..134a79ed --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs_1L/sc035hgs_1L_cmos_ex.h @@ -0,0 +1,82 @@ +#ifndef __SC035HGS_1L_CMOS_EX_H_ +#define __SC035HGS_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 sc035hgs_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_GAIN_MAGIC_2_ADDR, + LINEAR_GAIN_MAGIC_3_ADDR, + LINEAR_REGS_NUM +}; + +typedef enum _SC035HGS_1L_MODE_E { + SC035HGS_1L_MODE_640X480P120 = 0, + SC035HGS_1L_MODE_LINEAR_NUM, + SC035HGS_1L_MODE_NUM +} SC035HGS_1L_MODE_E; + +typedef struct _SC035HGS_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]; +} SC035HGS_1L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC035HGS_1L[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC035HGS_1L_BusInfo[]; +extern CVI_U16 g_au16SC035HGS_1L_GainMode[]; +extern CVI_U16 g_au16SC035HGS_1L_L2SMode[]; +extern const CVI_U8 sc035hgs_1L_i2c_addr; +extern const CVI_U32 sc035hgs_1L_addr_byte; +extern const CVI_U32 sc035hgs_1L_data_byte; +extern void sc035hgs_1L_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void sc035hgs_1L_init(VI_PIPE ViPipe); +extern void sc035hgs_1L_exit(VI_PIPE ViPipe); +extern void sc035hgs_1L_standby(VI_PIPE ViPipe); +extern void sc035hgs_1L_restart(VI_PIPE ViPipe); +extern int sc035hgs_1L_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc035hgs_1L_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC035HGS_1L_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs_1L/sc035hgs_1L_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs_1L/sc035hgs_1L_cmos_param.h new file mode 100644 index 00000000..d4962d43 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs_1L/sc035hgs_1L_cmos_param.h @@ -0,0 +1,126 @@ +#ifndef __SC035HGS_1L_CMOS_PARAM_H_ +#define __SC035HGS_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 "sc035hgs_1L_cmos_ex.h" + +static const SC035HGS_1L_MODE_S g_astSC035HGS_1L_mode[SC035HGS_1L_MODE_NUM] = { + [SC035HGS_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 = 0.95, /* 515 * 120 / 0xFFFF */ + .u32HtsDef = 1136, + .u32VtsDef = 528, + .stExp[0] = { + .u16Min = 1, + .u16Max = 522 << 4,// (vts - 6) * 16 + .u16Def = 400 << 4, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 15872, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 7936, + .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_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}, + .pn_swap = {0, 0, 0, 0, 0}, + .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 /* __SC035HGS_1L_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs_1L/sc035hgs_1L_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs_1L/sc035hgs_1L_sensor_ctl.c new file mode 100644 index 00000000..456e7a48 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc035hgs_1L/sc035hgs_1L_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 "sc035hgs_1L_cmos_ex.h" + +static void sc035hgs_1L_linear_1296P30_init(VI_PIPE ViPipe); + +const CVI_U8 sc035hgs_1L_i2c_addr = 0x32; /* I2C Address of SC035HGS_1L */ +const CVI_U32 sc035hgs_1L_addr_byte = 2; +const CVI_U32 sc035hgs_1L_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc035hgs_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_aunSC035HGS_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, sc035hgs_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 sc035hgs_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 sc035hgs_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 (sc035hgs_1L_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc035hgs_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, sc035hgs_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 (sc035hgs_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 sc035hgs_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 (sc035hgs_1L_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc035hgs_1L_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc035hgs_1L_addr_byte + sc035hgs_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 sc035hgs_1L_standby(VI_PIPE ViPipe) +{ + sc035hgs_1L_write_register(ViPipe, 0x0100, 0x00); +} + +void sc035hgs_1L_restart(VI_PIPE ViPipe) +{ + sc035hgs_1L_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc035hgs_1L_write_register(ViPipe, 0x0100, 0x01); +} + +void sc035hgs_1L_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC035HGS_1L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC035HGS_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc035hgs_1L_write_register(ViPipe, + g_pastSC035HGS_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC035HGS_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc035hgs_1L_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; + } + + sc035hgs_1L_write_register(ViPipe, 0x3221, val); +} + +void sc035hgs_1L_init(VI_PIPE ViPipe) +{ + sc035hgs_1L_i2c_init(ViPipe); + + //linear mode only + sc035hgs_1L_linear_1296P30_init(ViPipe); + + g_pastSC035HGS_1L[ViPipe]->bInit = CVI_TRUE; +} + +void sc035hgs_1L_exit(VI_PIPE ViPipe) +{ + sc035hgs_1L_i2c_exit(ViPipe); +} + +/* 1296P30 and 1296P25 */ +static void sc035hgs_1L_linear_1296P30_init(VI_PIPE ViPipe) +{ + sc035hgs_1L_write_register(ViPipe, 0x0103, 0x01); + delay_ms(33); + sc035hgs_1L_write_register(ViPipe, 0x0100, 0x00); + sc035hgs_1L_write_register(ViPipe, 0x0100, 0x00); + sc035hgs_1L_write_register(ViPipe, 0x36e9, 0x80); + sc035hgs_1L_write_register(ViPipe, 0x36f9, 0x80); + sc035hgs_1L_write_register(ViPipe, 0x3000, 0x00); + sc035hgs_1L_write_register(ViPipe, 0x3001, 0x00); + sc035hgs_1L_write_register(ViPipe, 0x300f, 0x0f); + sc035hgs_1L_write_register(ViPipe, 0x3018, 0x13); + sc035hgs_1L_write_register(ViPipe, 0x3019, 0xfe); + sc035hgs_1L_write_register(ViPipe, 0x301c, 0x78); + sc035hgs_1L_write_register(ViPipe, 0x301f, 0x62); + sc035hgs_1L_write_register(ViPipe, 0x3031, 0x0a); + sc035hgs_1L_write_register(ViPipe, 0x3037, 0x20); + sc035hgs_1L_write_register(ViPipe, 0x303f, 0x01); + sc035hgs_1L_write_register(ViPipe, 0x320c, 0x04); + sc035hgs_1L_write_register(ViPipe, 0x320d, 0x70); + sc035hgs_1L_write_register(ViPipe, 0x320e, 0x02); + sc035hgs_1L_write_register(ViPipe, 0x320f, 0x10); + sc035hgs_1L_write_register(ViPipe, 0x3217, 0x00); + sc035hgs_1L_write_register(ViPipe, 0x3218, 0x00); + sc035hgs_1L_write_register(ViPipe, 0x3220, 0x10); + sc035hgs_1L_write_register(ViPipe, 0x3223, 0x48); + sc035hgs_1L_write_register(ViPipe, 0x3226, 0x74); + sc035hgs_1L_write_register(ViPipe, 0x3227, 0x07); + sc035hgs_1L_write_register(ViPipe, 0x323b, 0x00); + sc035hgs_1L_write_register(ViPipe, 0x3250, 0xf0); + sc035hgs_1L_write_register(ViPipe, 0x3251, 0x02); // 0x1 + sc035hgs_1L_write_register(ViPipe, 0x3252, 0x02); // 0xf8 + sc035hgs_1L_write_register(ViPipe, 0x3253, 0x08); + sc035hgs_1L_write_register(ViPipe, 0x3254, 0x02); + sc035hgs_1L_write_register(ViPipe, 0x3255, 0x07); + sc035hgs_1L_write_register(ViPipe, 0x3304, 0x48); + sc035hgs_1L_write_register(ViPipe, 0x3305, 0x00); + sc035hgs_1L_write_register(ViPipe, 0x3306, 0x98); + sc035hgs_1L_write_register(ViPipe, 0x3309, 0x50); + sc035hgs_1L_write_register(ViPipe, 0x330a, 0x01); + sc035hgs_1L_write_register(ViPipe, 0x330b, 0x18); + sc035hgs_1L_write_register(ViPipe, 0x330c, 0x18); + sc035hgs_1L_write_register(ViPipe, 0x330f, 0x40); + sc035hgs_1L_write_register(ViPipe, 0x3310, 0x10); + sc035hgs_1L_write_register(ViPipe, 0x3314, 0x6b); + sc035hgs_1L_write_register(ViPipe, 0x3315, 0x30); + sc035hgs_1L_write_register(ViPipe, 0x3316, 0x68); + sc035hgs_1L_write_register(ViPipe, 0x3317, 0x14); + sc035hgs_1L_write_register(ViPipe, 0x3329, 0x5c); + sc035hgs_1L_write_register(ViPipe, 0x332d, 0x5c); + sc035hgs_1L_write_register(ViPipe, 0x332f, 0x60); + sc035hgs_1L_write_register(ViPipe, 0x3335, 0x64); + sc035hgs_1L_write_register(ViPipe, 0x3344, 0x64); + sc035hgs_1L_write_register(ViPipe, 0x335b, 0x80); + sc035hgs_1L_write_register(ViPipe, 0x335f, 0x80); + sc035hgs_1L_write_register(ViPipe, 0x3366, 0x06); + sc035hgs_1L_write_register(ViPipe, 0x3385, 0x31); + sc035hgs_1L_write_register(ViPipe, 0x3387, 0x39); + sc035hgs_1L_write_register(ViPipe, 0x3389, 0x01); + sc035hgs_1L_write_register(ViPipe, 0x33b1, 0x03); + sc035hgs_1L_write_register(ViPipe, 0x33b2, 0x06); + sc035hgs_1L_write_register(ViPipe, 0x33bd, 0xe0); + sc035hgs_1L_write_register(ViPipe, 0x33bf, 0x10); + sc035hgs_1L_write_register(ViPipe, 0x3621, 0xa4); + sc035hgs_1L_write_register(ViPipe, 0x3622, 0x05); + sc035hgs_1L_write_register(ViPipe, 0x3624, 0x47); + sc035hgs_1L_write_register(ViPipe, 0x3630, 0x4a); + sc035hgs_1L_write_register(ViPipe, 0x3631, 0x58); + sc035hgs_1L_write_register(ViPipe, 0x3633, 0x52); + sc035hgs_1L_write_register(ViPipe, 0x3635, 0x03); + sc035hgs_1L_write_register(ViPipe, 0x3636, 0x25); + sc035hgs_1L_write_register(ViPipe, 0x3637, 0x8a); + sc035hgs_1L_write_register(ViPipe, 0x3638, 0x0f); + sc035hgs_1L_write_register(ViPipe, 0x3639, 0x08); + sc035hgs_1L_write_register(ViPipe, 0x363a, 0x00); + sc035hgs_1L_write_register(ViPipe, 0x363b, 0x48); + sc035hgs_1L_write_register(ViPipe, 0x363c, 0x86); + sc035hgs_1L_write_register(ViPipe, 0x363d, 0x10); + sc035hgs_1L_write_register(ViPipe, 0x363e, 0xf8); + sc035hgs_1L_write_register(ViPipe, 0x3640, 0x00); + sc035hgs_1L_write_register(ViPipe, 0x3641, 0x01); + sc035hgs_1L_write_register(ViPipe, 0x36ea, 0x36); + sc035hgs_1L_write_register(ViPipe, 0x36eb, 0x0e); + sc035hgs_1L_write_register(ViPipe, 0x36ec, 0x0e); + sc035hgs_1L_write_register(ViPipe, 0x36ed, 0x10); + sc035hgs_1L_write_register(ViPipe, 0x36fa, 0x36); + sc035hgs_1L_write_register(ViPipe, 0x36fb, 0x10); + sc035hgs_1L_write_register(ViPipe, 0x36fc, 0x01); + sc035hgs_1L_write_register(ViPipe, 0x36fd, 0x00); + sc035hgs_1L_write_register(ViPipe, 0x3908, 0x91); + sc035hgs_1L_write_register(ViPipe, 0x391b, 0x81); + sc035hgs_1L_write_register(ViPipe, 0x3d08, 0x01); + sc035hgs_1L_write_register(ViPipe, 0x3e01, 0x18); + sc035hgs_1L_write_register(ViPipe, 0x3e02, 0xf0); + sc035hgs_1L_write_register(ViPipe, 0x3e03, 0x2b); + sc035hgs_1L_write_register(ViPipe, 0x3e06, 0x0c); + sc035hgs_1L_write_register(ViPipe, 0x3f04, 0x03); + sc035hgs_1L_write_register(ViPipe, 0x3f05, 0x80); + sc035hgs_1L_write_register(ViPipe, 0x4500, 0x59); + sc035hgs_1L_write_register(ViPipe, 0x4501, 0xc4); + sc035hgs_1L_write_register(ViPipe, 0x4603, 0x00); + sc035hgs_1L_write_register(ViPipe, 0x4800, 0x64); + sc035hgs_1L_write_register(ViPipe, 0x4809, 0x01); + sc035hgs_1L_write_register(ViPipe, 0x4810, 0x00); + sc035hgs_1L_write_register(ViPipe, 0x4811, 0x01); + sc035hgs_1L_write_register(ViPipe, 0x4837, 0x1c); + sc035hgs_1L_write_register(ViPipe, 0x5011, 0x00); + sc035hgs_1L_write_register(ViPipe, 0x5988, 0x02); + sc035hgs_1L_write_register(ViPipe, 0x598e, 0x04); + sc035hgs_1L_write_register(ViPipe, 0x598f, 0x4e); + sc035hgs_1L_write_register(ViPipe, 0x36e9, 0x44); + sc035hgs_1L_write_register(ViPipe, 0x36f9, 0x44); + sc035hgs_1L_write_register(ViPipe, 0x0100, 0x01); + sc035hgs_1L_write_register(ViPipe, 0x4418, 0x0a); + sc035hgs_1L_write_register(ViPipe, 0x4419, 0x80); + + sc035hgs_1L_default_reg_init(ViPipe); + + sc035hgs_1L_write_register(ViPipe, 0x0100, 0x01); + delay_ms(7); + sc035hgs_1L_write_register(ViPipe, 0x363d, 0x10); + sc035hgs_1L_write_register(ViPipe, 0x4418, 0x0a); + sc035hgs_1L_write_register(ViPipe, 0x4419, 0x80); + + delay_ms(100); + + printf("ViPipe:%d,===SC035HGS_1L 480P 120fps 12bit LINE Init OK!===3\n", ViPipe); +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1336_1L/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1336_1L/Makefile new file mode 100644 index 00000000..0249c1e0 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1336_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_sc1336_2l.a +TARGET_SO = $(MW_LIB)/libsns_sc1336_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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1336_1L/sc1336_1L_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1336_1L/sc1336_1L_cmos.c new file mode 100644 index 00000000..55e1281b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1336_1L/sc1336_1L_cmos.c @@ -0,0 +1,1372 @@ +#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 "sc1336_1L_cmos_ex.h" +#include "sc1336_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 SC1336_1L_ID 500 +#define SENSOR_SC1336_1L_WIDTH 1280 +#define SENSOR_SC1336_1L_HEIGHT 720 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC1336_1L[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC1336_1L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC1336_1L[dev]) +#define SC1336_1L_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC1336_1L[dev] = pstCtx) +#define SC1336_1L_SENSOR_RESET_CTX(dev) (g_pastSC1336_1L[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC1336_1L_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC1336_1L_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC1336_1L_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +SC1336_1L_STATE_S g_astSC1336_1L_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc1336_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); +/*****SC1336_1L Lines Range*****/ +#define SC1336_1L_FULL_LINES_MAX (0x7FFF) + +/*****SC1336_1L Register Address*****/ +#define SC1336_1L_SHS1_0_ADDR 0x3E00 +#define SC1336_1L_SHS1_1_ADDR 0x3E01 +#define SC1336_1L_SHS1_2_ADDR 0x3E02 +#define SC1336_1L_AGAIN_ADDR0 0x3E08 +#define SC1336_1L_AGAIN_ADDR1 0x3E09 +#define SC1336_1L_DGAIN_ADDR 0x3E06 +#define SC1336_1L_DGAIN_FINEADDR 0x3E07 +#define SC1336_1L_FLIP_MIRROR_ADDR 0x3221 +#define SC1336_1L_VMAX_ADDR 0x320E +#define SC1336_1L_TABLE_END 0xFFFF + +#define SC1336_1L_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 SC1336_1L_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 fps = 30; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC1336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC1336_1L_mode[pstSnsState->u8ImgMode]; + if ((pstSnsState->u8ImgMode == SC1336_1L_MODE_720P60) || + (pstSnsState->u8ImgMode == SC1336_1L_MODE_720P60_WDR)) + fps = 60; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC1336_1L_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * fps); + + 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 * fps / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + + 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: + 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 = pstSnsState->u32FLStd - 5; + pstAeSnsDft->u32MinIntTime = 1; + + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime; + + pstAeSnsDft->u32MaxAgain = 65536; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 32256; + 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; + } + 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); + SC1336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC1336_1L_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC1336_1L_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC1336_1L_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC1336_1L_MODE_720P30: + case SC1336_1L_MODE_720P30_WDR: + case SC1336_1L_MODE_720P60: + case SC1336_1L_MODE_720P60_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 > SC1336_1L_FULL_LINES_MAX) ? SC1336_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 { + 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 = 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; + + SC1336_1L_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 u32SeMaxLExp, u32LeMaxLExp, u32MinTime; + /* short exposure reg range: + * min : 2 + * max : (vts - 8) + * step : 4 + */ + u32MinTime = 2; + u32SeMaxLExp = pstSnsState->au32FL[0] - 8; + u16SexpReg = (u32ShortIntTime > u32SeMaxLExp) ? u32SeMaxLExp : u32ShortIntTime; + u16SexpReg = (u16SexpReg < u32MinTime) ? u32MinTime : u16SexpReg; + + /* long exposure reg range: + * min : 1 + * max : 2 * (vts - max sexp) + * step : 4 + */ + u32LeMaxLExp = pstSnsState->au32FL[0] - 8; + u16LexpReg = (u32LongIntTime > u32LeMaxLExp) ? u32LeMaxLExp : u32LongIntTime; + u16LexpReg = (u16LexpReg < u32MinTime) ? u32MinTime : u16LexpReg; + + pstSnsRegsInfo->astI2cData[WDR_SHS1_0_ADDR].u32Data = ((u16SexpReg & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[WDR_SHS1_1_ADDR].u32Data = ((u16SexpReg & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[WDR_SHS1_2_ADDR].u32Data = (u16SexpReg & 0xF) << 4; + pstSnsRegsInfo->astI2cData[WDR_SHS1_0_ADDR].u8DelayFrmNum = 1; + pstSnsRegsInfo->astI2cData[WDR_SHS1_1_ADDR].u8DelayFrmNum = 1; + pstSnsRegsInfo->astI2cData[WDR_SHS1_2_ADDR].u8DelayFrmNum = 1; + + pstSnsRegsInfo->astI2cData[WDR_SHS2_0_ADDR].u32Data = ((u16LexpReg & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[WDR_SHS2_1_ADDR].u32Data = ((u16LexpReg & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[WDR_SHS2_2_ADDR].u32Data = (u16LexpReg & 0xF) << 4; + } else { + CVI_U32 u32TmpIntTime = u32IntTime[0]; + CVI_U32 maxExp = 2 * pstSnsState->au32FL[0] - 8; + + /* linear exposure reg range: + * min : 3 + * max : 2 * vts - 8 + * 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; + CVI_U8 regCoarseGain;// for again coarse gain adjust,dgain the value is 0; +}; + +static struct gain_tbl_info_s AgainInfo[] = { + { + .gainMax = 2016, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + .regCoarseGain = 0x1f, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + .regCoarseGain = 0x3f, + }, + { + .gainMax = 8064, + .idxBase = 64, + .regGain = 0x08, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + .regCoarseGain = 0x3f, + }, + { + .gainMax = 16128, + .idxBase = 96, + .regGain = 0x09, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + .regCoarseGain = 0x3f, + }, + { + .gainMax = 32256, + .idxBase = 128, + .regGain = 0x0b, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + .regCoarseGain = 0x3f, + }, + { + .gainMax = 64512, + .idxBase = 160, + .regGain = 0x0f, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + .regCoarseGain = 0x3f, + }, + { + .gainMax = 65535, + .idxBase = 192, + .regGain = 0x1f, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + .regCoarseGain = 0x3f, + }, +}; + +static CVI_U32 Again_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, 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, + + 32768, 33792, 34816, 35840, 36864, 37888, 38912, 39936, + 40960, 41984, 43008, 44032, 45056, 46080, 47104, 48128, + 49152, 50176, 51200, 52224, 53248, 54272, 55296, 56320, + 57344, 58368, 59392, 60416, 61440, 62464, 63488, 64512, + + 65536, + +}; + + +static struct gain_tbl_info_s DgainInfo[] = { + { + .gainMax = 2016, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + .regCoarseGain = 0x0, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + .regCoarseGain = 0x0, + }, + { + .gainMax = 8064, + .idxBase = 64, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + .regCoarseGain = 0x0, + }, + { + .gainMax = 16128, + .idxBase = 96, + .regGain = 0x07, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + .regCoarseGain = 0x0, + }, + { + .gainMax = 32256, + .idxBase = 128, + .regGain = 0x0f, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + .regCoarseGain = 0x0, + }, +}; + +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, 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_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 = Again_tableSize-1; + return CVI_SUCCESS; + } + + for (i = 1; i < Again_tableSize; 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); + + 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 u16Mode = g_au16SC1336_1L_GainMode[ViPipe]; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + int i, tbl_num; + + SC1336_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 */ + + /* Again. */ + 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_ADDR0].u32Data = (info->regCoarseGain & 0xFF); + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_ADDR1].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_FINE_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); + } 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[WDR_AGAIN2_ADDR0].u32Data = (info->regCoarseGain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_AGAIN2_ADDR1].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR_AGAIN2_FINE_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[WDR_DGAIN2_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR_DGAIN2_FINE_ADDR].u32Data = (u32Dgain & 0xFF); + + /* 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[WDR_AGAIN1_ADDR0].u32Data = (info->regCoarseGain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_AGAIN1_ADDR1].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR_AGAIN1_FINE_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[WDR_DGAIN1_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR_DGAIN1_FINE_ADDR].u32Data = (u32Dgain & 0xFF); + + pstSnsRegsInfo->astI2cData[WDR_AGAIN2_ADDR0].u8DelayFrmNum = 1; + pstSnsRegsInfo->astI2cData[WDR_AGAIN2_ADDR1].u8DelayFrmNum = 1; + pstSnsRegsInfo->astI2cData[WDR_AGAIN2_FINE_ADDR].u8DelayFrmNum = 1; + pstSnsRegsInfo->astI2cData[WDR_DGAIN2_ADDR].u8DelayFrmNum = 1; + pstSnsRegsInfo->astI2cData[WDR_DGAIN2_FINE_ADDR].u8DelayFrmNum = 1; + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + /* Again. */ + 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[WDR_AGAIN1_ADDR0].u32Data = (info->regCoarseGain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_AGAIN2_ADDR0].u32Data = (info->regCoarseGain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_AGAIN1_ADDR1].u32Data = (info->regGain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_AGAIN2_ADDR1].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR_AGAIN1_FINE_ADDR].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_AGAIN2_FINE_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[WDR_DGAIN1_ADDR].u32Data = (info->regGain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_DGAIN2_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR_DGAIN1_FINE_ADDR].u32Data = (u32Dgain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_DGAIN2_FINE_ADDR].u32Data = (u32Dgain & 0xFF); + + pstSnsRegsInfo->astI2cData[WDR_AGAIN2_ADDR0].u8DelayFrmNum = 1; + pstSnsRegsInfo->astI2cData[WDR_AGAIN2_ADDR1].u8DelayFrmNum = 1; + pstSnsRegsInfo->astI2cData[WDR_AGAIN2_FINE_ADDR].u8DelayFrmNum = 1; + pstSnsRegsInfo->astI2cData[WDR_DGAIN2_ADDR].u8DelayFrmNum = 1; + pstSnsRegsInfo->astI2cData[WDR_DGAIN2_FINE_ADDR].u8DelayFrmNum = 1; + } + } + 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_astSC1336_1L_State[ViPipe].u32Sexp_MAX - 14; + + (void) u16ManRatioEnable; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + SC1336_1L_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 SC1336_1L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC1336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC1336_1L_mode[pstSnsState->u8ImgMode]; + + if (pstSnsState->enWDRMode != WDR_MODE_NONE) { + pstIspCfg->frm_num = 2; + memcpy(&pstIspCfg->img_size[0], &pstMode->stImg[0], sizeof(ISP_WDR_SIZE_S)); + memcpy(&pstIspCfg->img_size[1], &pstMode->stImg[1], sizeof(ISP_WDR_SIZE_S)); + } else { + 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; + + SC1336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == SC1336_1L_MODE_720P30_WDR) + pstSnsState->u8ImgMode = SC1336_1L_MODE_720P30; + else if (pstSnsState->u8ImgMode == SC1336_1L_MODE_720P60_WDR) + pstSnsState->u8ImgMode = SC1336_1L_MODE_720P60; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC1336_1L_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == SC1336_1L_MODE_720P30) + pstSnsState->u8ImgMode = SC1336_1L_MODE_720P30_WDR; + else if (pstSnsState->u8ImgMode == SC1336_1L_MODE_720P60) + pstSnsState->u8ImgMode = SC1336_1L_MODE_720P60_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astSC1336_1L_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "2to1 line WDR 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); + SC1336_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_aunSC1336_1L_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 = sc1336_1l_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc1336_1l_addr_byte; + pstI2c_data[i].u32DataByteNum = sc1336_1l_data_byte; + } + + //Linear Mode Regs + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[WDR_SHS1_0_ADDR].u32RegAddr = SC1336_1L_SHS1_0_ADDR; + pstI2c_data[WDR_SHS1_1_ADDR].u32RegAddr = SC1336_1L_SHS1_1_ADDR; + pstI2c_data[WDR_SHS1_2_ADDR].u32RegAddr = SC1336_1L_SHS1_2_ADDR; + pstI2c_data[WDR_SHS2_0_ADDR].u32RegAddr = SC1336_1L_SHS1_0_ADDR; + pstI2c_data[WDR_SHS2_1_ADDR].u32RegAddr = SC1336_1L_SHS1_1_ADDR; + pstI2c_data[WDR_SHS2_2_ADDR].u32RegAddr = SC1336_1L_SHS1_2_ADDR; + pstI2c_data[WDR_AGAIN1_ADDR0].u32RegAddr = SC1336_1L_AGAIN_ADDR0; + pstI2c_data[WDR_AGAIN1_ADDR1].u32RegAddr = SC1336_1L_AGAIN_ADDR1; + pstI2c_data[WDR_AGAIN1_FINE_ADDR].u32RegAddr = SC1336_1L_DGAIN_FINEADDR; + pstI2c_data[WDR_AGAIN2_ADDR0].u32RegAddr = SC1336_1L_AGAIN_ADDR0; + pstI2c_data[WDR_AGAIN2_ADDR1].u32RegAddr = SC1336_1L_AGAIN_ADDR1; + pstI2c_data[WDR_AGAIN2_FINE_ADDR].u32RegAddr = SC1336_1L_DGAIN_FINEADDR; + pstI2c_data[WDR_DGAIN1_ADDR].u32RegAddr = SC1336_1L_DGAIN_ADDR; + pstI2c_data[WDR_DGAIN1_FINE_ADDR].u32RegAddr = SC1336_1L_DGAIN_FINEADDR; + pstI2c_data[WDR_DGAIN2_ADDR].u32RegAddr = SC1336_1L_DGAIN_ADDR; + pstI2c_data[WDR_DGAIN2_FINE_ADDR].u32RegAddr = SC1336_1L_DGAIN_FINEADDR; + pstI2c_data[WDR_FLIP_MIRROR].u32RegAddr = SC1336_1L_FLIP_MIRROR_ADDR; + pstI2c_data[WDR_VMAX_H_ADDR].u32RegAddr = SC1336_1L_VMAX_ADDR; + pstI2c_data[WDR_VMAX_L_ADDR].u32RegAddr = SC1336_1L_VMAX_ADDR + 1; + break; + default: + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC1336_1L_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC1336_1L_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC1336_1L_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_ADDR0].u32RegAddr = SC1336_1L_AGAIN_ADDR0; + pstI2c_data[LINEAR_AGAIN_ADDR1].u32RegAddr = SC1336_1L_AGAIN_ADDR1; + pstI2c_data[LINEAR_AGAIN_FINE_ADDR].u32RegAddr = SC1336_1L_DGAIN_FINEADDR; + pstI2c_data[LINEAR_DGAIN_ADDR].u32RegAddr = SC1336_1L_DGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_FINE_ADDR].u32RegAddr = SC1336_1L_DGAIN_FINEADDR; + pstI2c_data[LINEAR_FLIP_MIRROR].u32RegAddr = SC1336_1L_FLIP_MIRROR_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC1336_1L_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC1336_1L_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; + } + /* always update exposure time on wdr mode */ + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (i <= WDR_SHS2_2_ADDR) { + 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; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) + pstCfg0->snsCfg.astI2cData[WDR_FLIP_MIRROR].bDropFrm = CVI_FALSE; + else + 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); + SC1336_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 (SC1336_1L_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC1336_1L_MODE_720P30; + } else { + goto ERROR; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (SC1336_1L_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC1336_1L_MODE_720P30_WDR; + } else { + goto ERROR; + } + } else { + goto ERROR; + } + } else if (pstSensorImageMode->f32Fps <= 60) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC1336_1L_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC1336_1L_MODE_720P60; + } else { + goto ERROR; + } + } else if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (SC1336_1L_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC1336_1L_MODE_720P60_WDR; + } else { + goto ERROR; + } + } else { + goto ERROR; + } + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; + +ERROR: + 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; +} + +static CVI_VOID sc1336_1l_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; + + SC1336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + if (pstSnsState->bInit == CVI_TRUE && g_aeSc1336_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; + } + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstSnsRegsInfo->astI2cData[WDR_FLIP_MIRROR].u32Data = value; + } else { + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u32Data = value; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u8DropFrmNum = 1; + } + g_aeSc1336_MirrorFip[ViPipe] = eSnsMirrorFlip; + } + +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC1336_1L_MODE_S *pstMode = CVI_NULL; + + SC1336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC1336_1L_MODE_720P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC1336_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; + + SC1336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc1336_1l_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC1336_1L_mode[pstSnsState->u8ImgMode].stImg->stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC1336_1L_mode[pstSnsState->u8ImgMode].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 = &sc1336_1l_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 = sc1336_1l_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc1336_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 sc1336_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC1336_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; + + SC1336_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)); + + SC1336_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; + + SC1336_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC1336_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 = SC1336_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, SC1336_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, SC1336_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, SC1336_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_au16SC1336_1L_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC1336_1L_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC1336_1L_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc1336_1l_standby, + .pfnRestart = sc1336_1l_restart, + .pfnMirrorFlip = sc1336_1l_mirror_flip, + .pfnWriteReg = sc1336_1l_write_register, + .pfnReadReg = sc1336_1l_read_register, + .pfnSetBusInfo = sc1336_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 = sc1336_1l_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1336_1L/sc1336_1L_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1336_1L/sc1336_1L_cmos_ex.h new file mode 100644 index 00000000..b2775203 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1336_1L/sc1336_1L_cmos_ex.h @@ -0,0 +1,111 @@ +#ifndef __SC1336_1L_CMOS_EX_H_ +#define __SC1336_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 sc1336_1l_linear_regs_e { + LINEAR_SHS1_0_ADDR, + LINEAR_SHS1_1_ADDR, + LINEAR_SHS1_2_ADDR, + LINEAR_AGAIN_ADDR0, + LINEAR_AGAIN_ADDR1, + LINEAR_AGAIN_FINE_ADDR, + LINEAR_DGAIN_ADDR, + LINEAR_DGAIN_FINE_ADDR, + LINEAR_FLIP_MIRROR, + LINEAR_VMAX_H_ADDR, + LINEAR_VMAX_L_ADDR, + LINEAR_REGS_NUM +}; + +enum sc1336_1l_dol2_regs_e { + WDR_SHS1_0_ADDR, + WDR_SHS1_1_ADDR, + WDR_SHS1_2_ADDR, + WDR_SHS2_0_ADDR, + WDR_SHS2_1_ADDR, + WDR_SHS2_2_ADDR, + WDR_AGAIN1_ADDR0, + WDR_AGAIN1_ADDR1, + WDR_AGAIN1_FINE_ADDR, + WDR_AGAIN2_ADDR0, + WDR_AGAIN2_ADDR1, + WDR_AGAIN2_FINE_ADDR, + WDR_DGAIN1_ADDR, + WDR_DGAIN1_FINE_ADDR, + WDR_DGAIN2_ADDR, + WDR_DGAIN2_FINE_ADDR, + WDR_FLIP_MIRROR, + WDR_VMAX_H_ADDR, + WDR_VMAX_L_ADDR, + WDR_REGS_NUM +}; + +typedef enum _SC1336_1L_MODE_E { + SC1336_1L_MODE_720P30 = 0, + SC1336_1L_MODE_720P60, + SC1336_1L_MODE_LINEAR_NUM, + SC1336_1L_MODE_720P30_WDR = SC1336_1L_MODE_LINEAR_NUM, + SC1336_1L_MODE_720P60_WDR, + SC1336_1L_MODE_NUM +} SC1336_1L_MODE_E; + +typedef struct _SC1336_1L_STATE_S { + CVI_U32 u32Sexp_MAX; /* (2*{16’h3e23,16’h3e24} – 'd10)/2 */ +} SC1336_1L_STATE_S; + +typedef struct _SC1336_1L_MODE_S { + ISP_WDR_SIZE_S stImg[2]; + 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; + CVI_U16 u16SexpMaxReg; /* {16’h3e23,16’h3e24} */ + char name[64]; +} SC1336_1L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC1336_1L[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC1336_1L_BusInfo[]; +extern CVI_U16 g_au16SC1336_1L_GainMode[]; +extern CVI_U16 g_au16SC1336_1L_L2SMode[]; +extern const CVI_U8 sc1336_1l_i2c_addr; +extern const CVI_U32 sc1336_1l_addr_byte; +extern const CVI_U32 sc1336_1l_data_byte; +extern void sc1336_1l_init(VI_PIPE ViPipe); +extern void sc1336_1l_exit(VI_PIPE ViPipe); +extern void sc1336_1l_standby(VI_PIPE ViPipe); +extern void sc1336_1l_restart(VI_PIPE ViPipe); +extern int sc1336_1l_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc1336_1l_read_register(VI_PIPE ViPipe, int addr); +extern int sc1336_1l_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC1336_1L_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1336_1L/sc1336_1L_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1336_1L/sc1336_1L_cmos_param.h new file mode 100644 index 00000000..91b4243b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1336_1L/sc1336_1L_cmos_param.h @@ -0,0 +1,347 @@ +#ifndef __SC1336_1L_CMOS_PARAM_H_ +#define __SC1336_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 "sc1336_1L_cmos_ex.h" + +static const SC1336_1L_MODE_S g_astSC1336_1L_mode[SC1336_1L_MODE_NUM] = { + [SC1336_1L_MODE_720P30] = { + .name = "720p30", + .stImg[0] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.37, /* 720 * 30 / 0x3FFF*/ + .u32HtsDef = 1280, + .u32VtsDef = 720, + .stExp = { + .u16Min = 2, + .u16Max = 1492,/* 2*vts-8 */ + .u16Def = 100, + .u16Step = 1, + }, + .stAgain = { + .u32Min = 1024, + .u32Max = 65536, /* 64x1024 */ + .u32Def = 1024, + .u32Step = 4, + }, + .stDgain = { + .u32Min = 1024, + .u32Max = 32256, /* 31.5x1024 */ + .u32Def = 1024, + .u32Step = 1, + }, + }, + [SC1336_1L_MODE_720P30_WDR] = { + .name = "720p30wdr", + .stImg[0] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + .stImg[1] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.37, /* 720 * 30 / 0x3FFF*/ + .u32HtsDef = 1280, + .u32VtsDef = 720, + .u16SexpMaxReg = 0x13E, + }, + [SC1336_1L_MODE_720P60] = { + .name = "720p60", + .stImg[0] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + .f32MaxFps = 60, + .f32MinFps = 2.74, /* 750 * 60 / 0x3FFF*/ + .u32HtsDef = 1280, + .u32VtsDef = 720, + .stExp = { + .u16Min = 2, + .u16Max = 750 - 6, + .u16Def = 100, + .u16Step = 1, + }, + .stAgain = { + .u32Min = 1024, + .u32Max = 32768, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain = { + .u32Min = 1024, + .u32Max = 4032, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [SC1336_1L_MODE_720P60_WDR] = { + .name = "720p60wdr", + .stImg[0] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + .stImg[1] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + .f32MaxFps = 60, + .f32MinFps = 1.37, /* 750 * 30 / 0x3FFF*/ + .u32HtsDef = 1280, + .u32VtsDef = 720, + .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 = { + {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 sc1336_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, 3, -1, -1, -1}, + .pn_swap = {1, 1, 0, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + .dphy = { + .enable = 1, + .hs_settle = 11, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC1336_1L_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1336_1L/sc1336_1L_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1336_1L/sc1336_1L_sensor_ctl.c new file mode 100644 index 00000000..db5e6094 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1336_1L/sc1336_1L_sensor_ctl.c @@ -0,0 +1,642 @@ +#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 "sc1336_1L_cmos_ex.h" + +static void sc1336_1l_linear_720p60_init(VI_PIPE ViPipe); +static void sc1336_1l_linear_720p30_init(VI_PIPE ViPipe); + +#define SC1336_1L_CHIP_ID_HI_ADDR 0x3107 +#define SC1336_1L_CHIP_ID_LO_ADDR 0x3108 +#define SC1336_1L_CHIP_ID 0xca3f + +const CVI_U8 sc1336_1l_i2c_addr = 0x30; /* I2C Address of SC1336_1L */ + +/*msg type address:16-bit data:8-bit dev addr:7-bit*/ +const CVI_U32 sc1336_1l_addr_byte = 2; +const CVI_U32 sc1336_1l_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc1336_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_aunSC1336_1L_BusInfo[ViPipe].s8I2cDev; + // printf("iic u8DevNum = %d\n", u8DevNum); + 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, sc1336_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 sc1336_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 sc1336_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 (sc1336_1l_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc1336_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, sc1336_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 (sc1336_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); + // printf("i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int sc1336_1l_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 (sc1336_1l_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc1336_1l_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc1336_1l_addr_byte + sc1336_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 sc1336_1l_standby(VI_PIPE ViPipe) +{ + sc1336_1l_write_register(ViPipe, 0x0100, 0x00); +} + +void sc1336_1l_restart(VI_PIPE ViPipe) +{ + sc1336_1l_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc1336_1l_write_register(ViPipe, 0x0100, 0x01); +} + +void sc1336_1l_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC1336_1L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc1336_1l_write_register(ViPipe, + g_pastSC1336_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC1336_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +int sc1336_1l_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc1336_1l_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc1336_1l_read_register(ViPipe, SC1336_1L_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 = sc1336_1l_read_register(ViPipe, SC1336_1L_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 != SC1336_1L_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc1336_1l_init(VI_PIPE ViPipe) +{ + CVI_U8 u8ImgMode = g_pastSC1336_1L[ViPipe]->u8ImgMode; + + sc1336_1l_i2c_init(ViPipe); + + if ((u8ImgMode == SC1336_1L_MODE_720P30) || (u8ImgMode == SC1336_1L_MODE_720P30_WDR)) + sc1336_1l_linear_720p30_init(ViPipe); + else if ((u8ImgMode == SC1336_1L_MODE_720P60) || (u8ImgMode == SC1336_1L_MODE_720P60_WDR)) + sc1336_1l_linear_720p60_init(ViPipe); + + g_pastSC1336_1L[ViPipe]->bInit = CVI_TRUE; +} + +void sc1336_1l_exit(VI_PIPE ViPipe) +{ + sc1336_1l_i2c_exit(ViPipe); +} + +/* 720P30 */ +static void sc1336_1l_linear_720p30_init(VI_PIPE ViPipe) +{ +/*****************************************************************/ + sc1336_1l_write_register(ViPipe, 0x0103, 0x01); + sc1336_1l_write_register(ViPipe, 0x0100, 0x00); + sc1336_1l_write_register(ViPipe, 0x36e9, 0x80); + sc1336_1l_write_register(ViPipe, 0x37f9, 0x80); + sc1336_1l_write_register(ViPipe, 0x3018, 0x1a); + sc1336_1l_write_register(ViPipe, 0x3019, 0x0e); + sc1336_1l_write_register(ViPipe, 0x301f, 0x14); + sc1336_1l_write_register(ViPipe, 0x3200, 0x00); + sc1336_1l_write_register(ViPipe, 0x3201, 0x00); + sc1336_1l_write_register(ViPipe, 0x3202, 0x00); + sc1336_1l_write_register(ViPipe, 0x3203, 0x00); + sc1336_1l_write_register(ViPipe, 0x3204, 0x05); + sc1336_1l_write_register(ViPipe, 0x3205, 0x07); + sc1336_1l_write_register(ViPipe, 0x3206, 0x02); + sc1336_1l_write_register(ViPipe, 0x3207, 0xd7); + sc1336_1l_write_register(ViPipe, 0x3208, 0x05); + sc1336_1l_write_register(ViPipe, 0x3209, 0x00); + sc1336_1l_write_register(ViPipe, 0x320a, 0x02); + sc1336_1l_write_register(ViPipe, 0x320b, 0xd0); + sc1336_1l_write_register(ViPipe, 0x320c, 0x06); + sc1336_1l_write_register(ViPipe, 0x320d, 0x40); + sc1336_1l_write_register(ViPipe, 0x3210, 0x00); + sc1336_1l_write_register(ViPipe, 0x3211, 0x04); + sc1336_1l_write_register(ViPipe, 0x3212, 0x00); + sc1336_1l_write_register(ViPipe, 0x3213, 0x04); + sc1336_1l_write_register(ViPipe, 0x3248, 0x04); + sc1336_1l_write_register(ViPipe, 0x3249, 0x0b); + sc1336_1l_write_register(ViPipe, 0x3250, 0x40); + sc1336_1l_write_register(ViPipe, 0x3301, 0x03); + sc1336_1l_write_register(ViPipe, 0x3302, 0x10); + sc1336_1l_write_register(ViPipe, 0x3303, 0x10); + sc1336_1l_write_register(ViPipe, 0x3304, 0x40); + sc1336_1l_write_register(ViPipe, 0x3306, 0x38); + sc1336_1l_write_register(ViPipe, 0x3307, 0x02); + sc1336_1l_write_register(ViPipe, 0x3308, 0x08); + sc1336_1l_write_register(ViPipe, 0x3309, 0x60); + sc1336_1l_write_register(ViPipe, 0x330a, 0x00); + sc1336_1l_write_register(ViPipe, 0x330b, 0x70); + sc1336_1l_write_register(ViPipe, 0x330c, 0x16); + sc1336_1l_write_register(ViPipe, 0x330d, 0x10); + sc1336_1l_write_register(ViPipe, 0x330e, 0x10); + sc1336_1l_write_register(ViPipe, 0x3318, 0x02); + sc1336_1l_write_register(ViPipe, 0x331c, 0x01); + sc1336_1l_write_register(ViPipe, 0x331e, 0x39); + sc1336_1l_write_register(ViPipe, 0x331f, 0x59); + sc1336_1l_write_register(ViPipe, 0x3327, 0x0a); + sc1336_1l_write_register(ViPipe, 0x3333, 0x10); + sc1336_1l_write_register(ViPipe, 0x3334, 0x40); + sc1336_1l_write_register(ViPipe, 0x335e, 0x06); + sc1336_1l_write_register(ViPipe, 0x335f, 0x0a); + sc1336_1l_write_register(ViPipe, 0x3364, 0x1f); + sc1336_1l_write_register(ViPipe, 0x337a, 0x02); + sc1336_1l_write_register(ViPipe, 0x337b, 0x06); + sc1336_1l_write_register(ViPipe, 0x337c, 0x02); + sc1336_1l_write_register(ViPipe, 0x337d, 0x0e); + sc1336_1l_write_register(ViPipe, 0x3390, 0x01); + sc1336_1l_write_register(ViPipe, 0x3391, 0x07); + sc1336_1l_write_register(ViPipe, 0x3392, 0x0f); + sc1336_1l_write_register(ViPipe, 0x3393, 0x03); + sc1336_1l_write_register(ViPipe, 0x3394, 0x03); + sc1336_1l_write_register(ViPipe, 0x3395, 0x03); + sc1336_1l_write_register(ViPipe, 0x3396, 0x48); + sc1336_1l_write_register(ViPipe, 0x3397, 0x49); + sc1336_1l_write_register(ViPipe, 0x3398, 0x4f); + sc1336_1l_write_register(ViPipe, 0x3399, 0x02); + sc1336_1l_write_register(ViPipe, 0x339a, 0x04); + sc1336_1l_write_register(ViPipe, 0x339b, 0x10); + sc1336_1l_write_register(ViPipe, 0x339c, 0x90); + sc1336_1l_write_register(ViPipe, 0x33a2, 0x04); + sc1336_1l_write_register(ViPipe, 0x33a3, 0x04); + sc1336_1l_write_register(ViPipe, 0x33ad, 0x0c); + sc1336_1l_write_register(ViPipe, 0x33b1, 0x80); + sc1336_1l_write_register(ViPipe, 0x33b2, 0x50); + sc1336_1l_write_register(ViPipe, 0x33b3, 0x38); + sc1336_1l_write_register(ViPipe, 0x33f9, 0x38); + sc1336_1l_write_register(ViPipe, 0x33fb, 0x48); + sc1336_1l_write_register(ViPipe, 0x33fc, 0x4b); + sc1336_1l_write_register(ViPipe, 0x33fd, 0x4f); + sc1336_1l_write_register(ViPipe, 0x349f, 0x03); + sc1336_1l_write_register(ViPipe, 0x34a6, 0x49); + sc1336_1l_write_register(ViPipe, 0x34a7, 0x4f); + sc1336_1l_write_register(ViPipe, 0x34a8, 0x28); + sc1336_1l_write_register(ViPipe, 0x34a9, 0x00); + sc1336_1l_write_register(ViPipe, 0x34aa, 0x00); + sc1336_1l_write_register(ViPipe, 0x34ab, 0x70); + sc1336_1l_write_register(ViPipe, 0x34ac, 0x00); + sc1336_1l_write_register(ViPipe, 0x34ad, 0x80); + sc1336_1l_write_register(ViPipe, 0x3630, 0xc0); + sc1336_1l_write_register(ViPipe, 0x3631, 0x84); + sc1336_1l_write_register(ViPipe, 0x3632, 0x78); + sc1336_1l_write_register(ViPipe, 0x3633, 0x42); + sc1336_1l_write_register(ViPipe, 0x3637, 0x2a); + sc1336_1l_write_register(ViPipe, 0x363a, 0x88); + sc1336_1l_write_register(ViPipe, 0x363b, 0x03); + sc1336_1l_write_register(ViPipe, 0x363c, 0x08); + sc1336_1l_write_register(ViPipe, 0x3641, 0x3a); + sc1336_1l_write_register(ViPipe, 0x3670, 0x0f); + sc1336_1l_write_register(ViPipe, 0x3674, 0xb0); + sc1336_1l_write_register(ViPipe, 0x3675, 0xc0); + sc1336_1l_write_register(ViPipe, 0x3676, 0xc0); + sc1336_1l_write_register(ViPipe, 0x367c, 0x40); + sc1336_1l_write_register(ViPipe, 0x367d, 0x48); + sc1336_1l_write_register(ViPipe, 0x3690, 0x33); + sc1336_1l_write_register(ViPipe, 0x3691, 0x43); + sc1336_1l_write_register(ViPipe, 0x3692, 0x53); + sc1336_1l_write_register(ViPipe, 0x3693, 0x84); + sc1336_1l_write_register(ViPipe, 0x3694, 0x88); + sc1336_1l_write_register(ViPipe, 0x3695, 0x8c); + sc1336_1l_write_register(ViPipe, 0x3698, 0x89); + sc1336_1l_write_register(ViPipe, 0x3699, 0x92); + sc1336_1l_write_register(ViPipe, 0x369a, 0xa5); + sc1336_1l_write_register(ViPipe, 0x369b, 0xca); + sc1336_1l_write_register(ViPipe, 0x369c, 0x48); + sc1336_1l_write_register(ViPipe, 0x369d, 0x4f); + sc1336_1l_write_register(ViPipe, 0x369e, 0x48); + sc1336_1l_write_register(ViPipe, 0x369f, 0x4b); + sc1336_1l_write_register(ViPipe, 0x36a2, 0x49); + sc1336_1l_write_register(ViPipe, 0x36a3, 0x4b); + sc1336_1l_write_register(ViPipe, 0x36a4, 0x4f); + sc1336_1l_write_register(ViPipe, 0x36a6, 0x49); + sc1336_1l_write_register(ViPipe, 0x36a7, 0x4b); + sc1336_1l_write_register(ViPipe, 0x36ab, 0x74); + sc1336_1l_write_register(ViPipe, 0x36ac, 0x74); + sc1336_1l_write_register(ViPipe, 0x36ad, 0x78); + sc1336_1l_write_register(ViPipe, 0x36d0, 0x01); + sc1336_1l_write_register(ViPipe, 0x36ea, 0x0c); + sc1336_1l_write_register(ViPipe, 0x36eb, 0x1c); + sc1336_1l_write_register(ViPipe, 0x36ec, 0x0c); + sc1336_1l_write_register(ViPipe, 0x36ed, 0x28); + sc1336_1l_write_register(ViPipe, 0x370f, 0x01); + sc1336_1l_write_register(ViPipe, 0x3722, 0x01); + sc1336_1l_write_register(ViPipe, 0x3724, 0x41); + sc1336_1l_write_register(ViPipe, 0x3725, 0xc4); + sc1336_1l_write_register(ViPipe, 0x37b0, 0x01); + sc1336_1l_write_register(ViPipe, 0x37b1, 0x01); + sc1336_1l_write_register(ViPipe, 0x37b2, 0x01); + sc1336_1l_write_register(ViPipe, 0x37b3, 0x4b); + sc1336_1l_write_register(ViPipe, 0x37b4, 0x4f); + sc1336_1l_write_register(ViPipe, 0x37fa, 0x0c); + sc1336_1l_write_register(ViPipe, 0x37fb, 0x35); + sc1336_1l_write_register(ViPipe, 0x37fc, 0x01); + sc1336_1l_write_register(ViPipe, 0x37fd, 0x07); + sc1336_1l_write_register(ViPipe, 0x3900, 0x0d); + sc1336_1l_write_register(ViPipe, 0x3902, 0xdf); + sc1336_1l_write_register(ViPipe, 0x3905, 0xb8); + sc1336_1l_write_register(ViPipe, 0x3908, 0x41); + sc1336_1l_write_register(ViPipe, 0x391b, 0x81); + sc1336_1l_write_register(ViPipe, 0x391c, 0x10); + sc1336_1l_write_register(ViPipe, 0x391f, 0x30); + sc1336_1l_write_register(ViPipe, 0x3933, 0x81); + sc1336_1l_write_register(ViPipe, 0x3934, 0xd9); + sc1336_1l_write_register(ViPipe, 0x3940, 0x70); + sc1336_1l_write_register(ViPipe, 0x3941, 0x00); + sc1336_1l_write_register(ViPipe, 0x3942, 0x01); + sc1336_1l_write_register(ViPipe, 0x3943, 0xdc); + sc1336_1l_write_register(ViPipe, 0x3952, 0x02); + sc1336_1l_write_register(ViPipe, 0x3953, 0x0f); + sc1336_1l_write_register(ViPipe, 0x3e01, 0x5d); + sc1336_1l_write_register(ViPipe, 0x3e02, 0x80); + sc1336_1l_write_register(ViPipe, 0x3e08, 0x1f); + sc1336_1l_write_register(ViPipe, 0x3e1b, 0x14); + sc1336_1l_write_register(ViPipe, 0x4509, 0x1c); + sc1336_1l_write_register(ViPipe, 0x4800, 0x44); + sc1336_1l_write_register(ViPipe, 0x4819, 0x05); + sc1336_1l_write_register(ViPipe, 0x481b, 0x03); + sc1336_1l_write_register(ViPipe, 0x481d, 0x0a); + sc1336_1l_write_register(ViPipe, 0x481f, 0x02); + sc1336_1l_write_register(ViPipe, 0x4821, 0x08); + sc1336_1l_write_register(ViPipe, 0x4823, 0x03); + sc1336_1l_write_register(ViPipe, 0x4825, 0x02); + sc1336_1l_write_register(ViPipe, 0x4827, 0x03); + sc1336_1l_write_register(ViPipe, 0x4829, 0x04); + sc1336_1l_write_register(ViPipe, 0x4831, 0x02); + sc1336_1l_write_register(ViPipe, 0x5799, 0x06); + sc1336_1l_write_register(ViPipe, 0x5ae0, 0xfe); + sc1336_1l_write_register(ViPipe, 0x5ae1, 0x40); + sc1336_1l_write_register(ViPipe, 0x5ae2, 0x30); + sc1336_1l_write_register(ViPipe, 0x5ae3, 0x28); + sc1336_1l_write_register(ViPipe, 0x5ae4, 0x20); + sc1336_1l_write_register(ViPipe, 0x5ae5, 0x30); + sc1336_1l_write_register(ViPipe, 0x5ae6, 0x28); + sc1336_1l_write_register(ViPipe, 0x5ae7, 0x20); + sc1336_1l_write_register(ViPipe, 0x5ae8, 0x3c); + sc1336_1l_write_register(ViPipe, 0x5ae9, 0x30); + sc1336_1l_write_register(ViPipe, 0x5aea, 0x28); + sc1336_1l_write_register(ViPipe, 0x5aeb, 0x3c); + sc1336_1l_write_register(ViPipe, 0x5aec, 0x30); + sc1336_1l_write_register(ViPipe, 0x5aed, 0x28); + sc1336_1l_write_register(ViPipe, 0x5aee, 0xfe); + sc1336_1l_write_register(ViPipe, 0x5aef, 0x40); + sc1336_1l_write_register(ViPipe, 0x5af4, 0x30); + sc1336_1l_write_register(ViPipe, 0x5af5, 0x28); + sc1336_1l_write_register(ViPipe, 0x5af6, 0x20); + sc1336_1l_write_register(ViPipe, 0x5af7, 0x30); + sc1336_1l_write_register(ViPipe, 0x5af8, 0x28); + sc1336_1l_write_register(ViPipe, 0x5af9, 0x20); + sc1336_1l_write_register(ViPipe, 0x5afa, 0x3c); + sc1336_1l_write_register(ViPipe, 0x5afb, 0x30); + sc1336_1l_write_register(ViPipe, 0x5afc, 0x28); + sc1336_1l_write_register(ViPipe, 0x5afd, 0x3c); + sc1336_1l_write_register(ViPipe, 0x5afe, 0x30); + sc1336_1l_write_register(ViPipe, 0x5aff, 0x28); + sc1336_1l_write_register(ViPipe, 0x36e9, 0x20); + sc1336_1l_write_register(ViPipe, 0x37f9, 0x27); + // sc1336_1l_write_register(ViPipe, 0x0100, 0x01); +/*****************************************************************/ + + sc1336_1l_default_reg_init(ViPipe); + + sc1336_1l_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC1336_1L 720P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +/* 720P60 */ +static void sc1336_1l_linear_720p60_init(VI_PIPE ViPipe) +{ + + sc1336_1l_write_register(ViPipe, 0x0103, 0x01); + sc1336_1l_write_register(ViPipe, 0x0100, 0x00); + sc1336_1l_write_register(ViPipe, 0x36e9, 0x80); + sc1336_1l_write_register(ViPipe, 0x37f9, 0x80); + sc1336_1l_write_register(ViPipe, 0x3018, 0x1a); + sc1336_1l_write_register(ViPipe, 0x3019, 0x0e); + sc1336_1l_write_register(ViPipe, 0x301f, 0x1b); + sc1336_1l_write_register(ViPipe, 0x320c, 0x06); + sc1336_1l_write_register(ViPipe, 0x320d, 0x04); + sc1336_1l_write_register(ViPipe, 0x320e, 0x03); + sc1336_1l_write_register(ViPipe, 0x320f, 0x0c); + sc1336_1l_write_register(ViPipe, 0x3248, 0x04); + sc1336_1l_write_register(ViPipe, 0x3249, 0x0b); + sc1336_1l_write_register(ViPipe, 0x3301, 0x04); + sc1336_1l_write_register(ViPipe, 0x3302, 0x10); + sc1336_1l_write_register(ViPipe, 0x3303, 0x10); + sc1336_1l_write_register(ViPipe, 0x3304, 0x40); + sc1336_1l_write_register(ViPipe, 0x3306, 0x38); + sc1336_1l_write_register(ViPipe, 0x3307, 0x02); + sc1336_1l_write_register(ViPipe, 0x3308, 0x08); + sc1336_1l_write_register(ViPipe, 0x3309, 0x60); + sc1336_1l_write_register(ViPipe, 0x330a, 0x00); + sc1336_1l_write_register(ViPipe, 0x330b, 0xa0); + sc1336_1l_write_register(ViPipe, 0x330c, 0x16); + sc1336_1l_write_register(ViPipe, 0x330d, 0x10); + sc1336_1l_write_register(ViPipe, 0x330e, 0x10); + sc1336_1l_write_register(ViPipe, 0x3318, 0x02); + sc1336_1l_write_register(ViPipe, 0x331e, 0x39); + sc1336_1l_write_register(ViPipe, 0x331f, 0x59); + sc1336_1l_write_register(ViPipe, 0x3327, 0x0a); + sc1336_1l_write_register(ViPipe, 0x3333, 0x10); + sc1336_1l_write_register(ViPipe, 0x3334, 0x40); + sc1336_1l_write_register(ViPipe, 0x335e, 0x06); + sc1336_1l_write_register(ViPipe, 0x335f, 0x0a); + sc1336_1l_write_register(ViPipe, 0x3364, 0x1f); + sc1336_1l_write_register(ViPipe, 0x337a, 0x02); + sc1336_1l_write_register(ViPipe, 0x337b, 0x06); + sc1336_1l_write_register(ViPipe, 0x337c, 0x02); + sc1336_1l_write_register(ViPipe, 0x337d, 0x0e); + sc1336_1l_write_register(ViPipe, 0x3390, 0x01); + sc1336_1l_write_register(ViPipe, 0x3391, 0x07); + sc1336_1l_write_register(ViPipe, 0x3392, 0x0f); + sc1336_1l_write_register(ViPipe, 0x3393, 0x04); + sc1336_1l_write_register(ViPipe, 0x3394, 0x04); + sc1336_1l_write_register(ViPipe, 0x3395, 0x04); + sc1336_1l_write_register(ViPipe, 0x3396, 0x48); + sc1336_1l_write_register(ViPipe, 0x3397, 0x49); + sc1336_1l_write_register(ViPipe, 0x3398, 0x4f); + sc1336_1l_write_register(ViPipe, 0x3399, 0x04); + sc1336_1l_write_register(ViPipe, 0x339a, 0x05); + sc1336_1l_write_register(ViPipe, 0x339b, 0x20); + sc1336_1l_write_register(ViPipe, 0x339c, 0x38); + sc1336_1l_write_register(ViPipe, 0x33a2, 0x04); + sc1336_1l_write_register(ViPipe, 0x33a3, 0x04); + sc1336_1l_write_register(ViPipe, 0x33ad, 0x0c); + sc1336_1l_write_register(ViPipe, 0x33b1, 0x80); + sc1336_1l_write_register(ViPipe, 0x33b2, 0x54); + sc1336_1l_write_register(ViPipe, 0x33b3, 0x48); + sc1336_1l_write_register(ViPipe, 0x33f9, 0x48); + sc1336_1l_write_register(ViPipe, 0x33fb, 0x68); + sc1336_1l_write_register(ViPipe, 0x33fc, 0x49); + sc1336_1l_write_register(ViPipe, 0x33fd, 0x4f); + sc1336_1l_write_register(ViPipe, 0x349f, 0x03); + sc1336_1l_write_register(ViPipe, 0x34a6, 0x49); + sc1336_1l_write_register(ViPipe, 0x34a7, 0x4f); + sc1336_1l_write_register(ViPipe, 0x34a8, 0x30); + sc1336_1l_write_register(ViPipe, 0x34a9, 0x18); + sc1336_1l_write_register(ViPipe, 0x34aa, 0x00); + sc1336_1l_write_register(ViPipe, 0x34ab, 0xa8); + sc1336_1l_write_register(ViPipe, 0x34ac, 0x00); + sc1336_1l_write_register(ViPipe, 0x34ad, 0xc8); + sc1336_1l_write_register(ViPipe, 0x3630, 0xc0); + sc1336_1l_write_register(ViPipe, 0x3631, 0x84); + sc1336_1l_write_register(ViPipe, 0x3632, 0x74); + sc1336_1l_write_register(ViPipe, 0x3633, 0x52); + sc1336_1l_write_register(ViPipe, 0x3637, 0x2a); + sc1336_1l_write_register(ViPipe, 0x363a, 0x89); + sc1336_1l_write_register(ViPipe, 0x363b, 0x03); + sc1336_1l_write_register(ViPipe, 0x363c, 0x08); + sc1336_1l_write_register(ViPipe, 0x3641, 0x3a); + sc1336_1l_write_register(ViPipe, 0x3670, 0x0f); + sc1336_1l_write_register(ViPipe, 0x3674, 0xb0); + sc1336_1l_write_register(ViPipe, 0x3675, 0xc0); + sc1336_1l_write_register(ViPipe, 0x3676, 0xc0); + sc1336_1l_write_register(ViPipe, 0x367c, 0x40); + sc1336_1l_write_register(ViPipe, 0x367d, 0x48); + sc1336_1l_write_register(ViPipe, 0x3690, 0x43); + sc1336_1l_write_register(ViPipe, 0x3691, 0x43); + sc1336_1l_write_register(ViPipe, 0x3692, 0x63); + sc1336_1l_write_register(ViPipe, 0x3693, 0x84); + sc1336_1l_write_register(ViPipe, 0x3694, 0x88); + sc1336_1l_write_register(ViPipe, 0x3695, 0x8a); + sc1336_1l_write_register(ViPipe, 0x3698, 0x89); + sc1336_1l_write_register(ViPipe, 0x3699, 0x92); + sc1336_1l_write_register(ViPipe, 0x369a, 0xa5); + sc1336_1l_write_register(ViPipe, 0x369b, 0xca); + sc1336_1l_write_register(ViPipe, 0x369c, 0x48); + sc1336_1l_write_register(ViPipe, 0x369d, 0x5f); + sc1336_1l_write_register(ViPipe, 0x369e, 0x48); + sc1336_1l_write_register(ViPipe, 0x369f, 0x4b); + sc1336_1l_write_register(ViPipe, 0x36a2, 0x49); + sc1336_1l_write_register(ViPipe, 0x36a3, 0x4b); + sc1336_1l_write_register(ViPipe, 0x36a4, 0x4f); + sc1336_1l_write_register(ViPipe, 0x36a6, 0x49); + sc1336_1l_write_register(ViPipe, 0x36a7, 0x4b); + sc1336_1l_write_register(ViPipe, 0x36ab, 0x74); + sc1336_1l_write_register(ViPipe, 0x36ac, 0x74); + sc1336_1l_write_register(ViPipe, 0x36ad, 0x78); + sc1336_1l_write_register(ViPipe, 0x36d0, 0x01); + sc1336_1l_write_register(ViPipe, 0x36ea, 0x06); + sc1336_1l_write_register(ViPipe, 0x36eb, 0x0c); + sc1336_1l_write_register(ViPipe, 0x36ec, 0x0c); + sc1336_1l_write_register(ViPipe, 0x36ed, 0x28); + sc1336_1l_write_register(ViPipe, 0x370f, 0x01); + sc1336_1l_write_register(ViPipe, 0x3722, 0x01); + sc1336_1l_write_register(ViPipe, 0x3724, 0x41); + sc1336_1l_write_register(ViPipe, 0x3725, 0xc4); + sc1336_1l_write_register(ViPipe, 0x37b0, 0x01); + sc1336_1l_write_register(ViPipe, 0x37b1, 0x01); + sc1336_1l_write_register(ViPipe, 0x37b2, 0x01); + sc1336_1l_write_register(ViPipe, 0x37b3, 0x4f); + sc1336_1l_write_register(ViPipe, 0x37b4, 0x5f); + sc1336_1l_write_register(ViPipe, 0x37fa, 0x09); + sc1336_1l_write_register(ViPipe, 0x37fb, 0x32); + sc1336_1l_write_register(ViPipe, 0x37fc, 0x01); + sc1336_1l_write_register(ViPipe, 0x37fd, 0x17); + sc1336_1l_write_register(ViPipe, 0x3900, 0x0d); + sc1336_1l_write_register(ViPipe, 0x3902, 0xdf); + sc1336_1l_write_register(ViPipe, 0x3905, 0xb8); + sc1336_1l_write_register(ViPipe, 0x3908, 0x41); + sc1336_1l_write_register(ViPipe, 0x391b, 0x81); + sc1336_1l_write_register(ViPipe, 0x391c, 0x10); + sc1336_1l_write_register(ViPipe, 0x391f, 0x30); + sc1336_1l_write_register(ViPipe, 0x3933, 0x81); + sc1336_1l_write_register(ViPipe, 0x3934, 0xd4); + sc1336_1l_write_register(ViPipe, 0x3940, 0x6b); + sc1336_1l_write_register(ViPipe, 0x3941, 0x00); + sc1336_1l_write_register(ViPipe, 0x3942, 0x01); + sc1336_1l_write_register(ViPipe, 0x3943, 0xd7); + sc1336_1l_write_register(ViPipe, 0x3952, 0x02); + sc1336_1l_write_register(ViPipe, 0x3953, 0x0f); + sc1336_1l_write_register(ViPipe, 0x3e01, 0x61); + sc1336_1l_write_register(ViPipe, 0x3e02, 0x00); + sc1336_1l_write_register(ViPipe, 0x3e08, 0x1f); + sc1336_1l_write_register(ViPipe, 0x3e1b, 0x14); + sc1336_1l_write_register(ViPipe, 0x4509, 0x1c); + sc1336_1l_write_register(ViPipe, 0x4819, 0x09); + sc1336_1l_write_register(ViPipe, 0x481b, 0x05); + sc1336_1l_write_register(ViPipe, 0x481d, 0x13); + sc1336_1l_write_register(ViPipe, 0x481f, 0x04); + sc1336_1l_write_register(ViPipe, 0x4821, 0x0a); + sc1336_1l_write_register(ViPipe, 0x4823, 0x05); + sc1336_1l_write_register(ViPipe, 0x4825, 0x04); + sc1336_1l_write_register(ViPipe, 0x4827, 0x05); + sc1336_1l_write_register(ViPipe, 0x4829, 0x08); + sc1336_1l_write_register(ViPipe, 0x4831, 0x02); + sc1336_1l_write_register(ViPipe, 0x5799, 0x06); + sc1336_1l_write_register(ViPipe, 0x5ae0, 0xfe); + sc1336_1l_write_register(ViPipe, 0x5ae1, 0x40); + sc1336_1l_write_register(ViPipe, 0x5ae2, 0x30); + sc1336_1l_write_register(ViPipe, 0x5ae3, 0x28); + sc1336_1l_write_register(ViPipe, 0x5ae4, 0x20); + sc1336_1l_write_register(ViPipe, 0x5ae5, 0x30); + sc1336_1l_write_register(ViPipe, 0x5ae6, 0x28); + sc1336_1l_write_register(ViPipe, 0x5ae7, 0x20); + sc1336_1l_write_register(ViPipe, 0x5ae8, 0x3c); + sc1336_1l_write_register(ViPipe, 0x5ae9, 0x30); + sc1336_1l_write_register(ViPipe, 0x5aea, 0x28); + sc1336_1l_write_register(ViPipe, 0x5aeb, 0x3c); + sc1336_1l_write_register(ViPipe, 0x5aec, 0x30); + sc1336_1l_write_register(ViPipe, 0x5aed, 0x28); + sc1336_1l_write_register(ViPipe, 0x5aee, 0xfe); + sc1336_1l_write_register(ViPipe, 0x5aef, 0x40); + sc1336_1l_write_register(ViPipe, 0x5af4, 0x30); + sc1336_1l_write_register(ViPipe, 0x5af5, 0x28); + sc1336_1l_write_register(ViPipe, 0x5af6, 0x20); + sc1336_1l_write_register(ViPipe, 0x5af7, 0x30); + sc1336_1l_write_register(ViPipe, 0x5af8, 0x28); + sc1336_1l_write_register(ViPipe, 0x5af9, 0x20); + sc1336_1l_write_register(ViPipe, 0x5afa, 0x3c); + sc1336_1l_write_register(ViPipe, 0x5afb, 0x30); + sc1336_1l_write_register(ViPipe, 0x5afc, 0x28); + sc1336_1l_write_register(ViPipe, 0x5afd, 0x3c); + sc1336_1l_write_register(ViPipe, 0x5afe, 0x30); + sc1336_1l_write_register(ViPipe, 0x5aff, 0x28); + sc1336_1l_write_register(ViPipe, 0x36e9, 0x24); + sc1336_1l_write_register(ViPipe, 0x37f9, 0x24); + + + sc1336_1l_default_reg_init(ViPipe); + + sc1336_1l_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC1336_1L 720P 60fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L/Makefile new file mode 100644 index 00000000..4b5d455b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_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_sc1346_1l.a +TARGET_SO = $(MW_LIB)/libsns_sc1346_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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L/sc1346_1L_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L/sc1346_1L_cmos.c new file mode 100644 index 00000000..6239226a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L/sc1346_1L_cmos.c @@ -0,0 +1,1326 @@ +#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 "sc1346_1L_cmos_ex.h" +#include "sc1346_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 SC1346_1L_ID 35 +#define SENSOR_SC1346_1L_WIDTH 1280 +#define SENSOR_SC1346_1L_HEIGHT 720 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC1346_1L[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC1346_1L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC1346_1L[dev]) +#define SC1346_1L_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC1346_1L[dev] = pstCtx) +#define SC1346_1L_SENSOR_RESET_CTX(dev) (g_pastSC1346_1L[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC1346_1L_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC1346_1L_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC1346_1L_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +SC1346_1L_STATE_S g_astSC1346_1L_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc1346_MirrorFip[VI_MAX_PIPE_NUM] = {ISP_SNS_NORMAL}; +/**************************************************************************** + * 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 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); +/*****SC1346_1L Lines Range*****/ +#define SC1346_1L_FULL_LINES_MAX (0x3FFF) + +/*****SC1346_1L Register Address*****/ +#define SC1346_1L_SHS1_0_ADDR 0x3E00 +#define SC1346_1L_SHS1_1_ADDR 0x3E01 +#define SC1346_1L_SHS1_2_ADDR 0x3E02 +#define SC1346_1L_AGAIN_ADDR 0x3E09 +#define SC1346_1L_DGAIN0_ADDR 0x3E06 +#define SC1346_1L_VMAX_ADDR 0x320E +#define SC1346_1L_FLIP_MIRROR_ADDR 0x3221 +#define SC1346_1L_TABLE_END 0xFFFF + +#define SC1346_1L_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 SC1346_1L_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 fps = 30; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC1346_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC1346_1L_mode[pstSnsState->u8ImgMode]; + if ((pstSnsState->u8ImgMode == SC1346_1L_MODE_720P60) || + (pstSnsState->u8ImgMode == SC1346_1L_MODE_720P60_WDR)) + fps = 60; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC1346_1L_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_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 * fps / 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; + 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 = 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; + } + 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); + SC1346_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC1346_1L_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC1346_1L_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC1346_1L_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC1346_1L_MODE_720P30: + case SC1346_1L_MODE_720P30_WDR: + case SC1346_1L_MODE_720P60: + case SC1346_1L_MODE_720P60_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 > SC1346_1L_FULL_LINES_MAX) ? SC1346_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_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; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC1346_1L_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 u32SeMaxLExp, u32LeMaxLExp, u32MinTime; + /* short exposure reg range: + * min : 2 + * max : (vts - 6) + * step : 4 + */ + u32MinTime = 2; + u32SeMaxLExp = pstSnsState->au32FL[0] - 6; + u16SexpReg = (u32ShortIntTime > u32SeMaxLExp) ? u32SeMaxLExp : u32ShortIntTime; + u16SexpReg = (u16SexpReg < u32MinTime) ? u32MinTime : u16SexpReg; + + /* long exposure reg range: + * min : 1 + * max : 2 * (vts - max sexp) + * step : 4 + */ + u32LeMaxLExp = pstSnsState->au32FL[0] - 6; + u16LexpReg = (u32LongIntTime > u32LeMaxLExp) ? u32LeMaxLExp : u32LongIntTime; + u16LexpReg = (u16LexpReg < u32MinTime) ? u32MinTime : u16LexpReg; + + pstSnsRegsInfo->astI2cData[WDR_SHS1_0_ADDR].u32Data = ((u16SexpReg & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[WDR_SHS1_1_ADDR].u32Data = ((u16SexpReg & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[WDR_SHS1_2_ADDR].u32Data = (u16SexpReg & 0xF) << 4; + pstSnsRegsInfo->astI2cData[WDR_SHS1_0_ADDR].u8DelayFrmNum = 1; + pstSnsRegsInfo->astI2cData[WDR_SHS1_1_ADDR].u8DelayFrmNum = 1; + pstSnsRegsInfo->astI2cData[WDR_SHS1_2_ADDR].u8DelayFrmNum = 1; + + pstSnsRegsInfo->astI2cData[WDR_SHS2_0_ADDR].u32Data = ((u16LexpReg & 0xF000) >> 12); + pstSnsRegsInfo->astI2cData[WDR_SHS2_1_ADDR].u32Data = ((u16LexpReg & 0x0FF0) >> 4); + pstSnsRegsInfo->astI2cData[WDR_SHS2_2_ADDR].u32Data = (u16LexpReg & 0xF) << 4; + } else { + + /* linear exposure reg range: + * min : 2 + * max : (vts - 6) + * step : 1 + */ + + u32MinTime = 2; + u32MaxTime = pstSnsState->au32FL[0] - 6; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : 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[] = { + { + .gainMax = 2016, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x08, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 8064, + .idxBase = 64, + .regGain = 0x09, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 16128, + .idxBase = 96, + .regGain = 0x0b, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 32256, + .idxBase = 128, + .regGain = 0x0f, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 32768, + .idxBase = 160, + .regGain = 0x1F, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, +}; + +static CVI_U32 Again_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, 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, + + 32768, +}; + +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, + }, +}; + +static CVI_U32 Dgain_table[] = { + /* 1x-2x */ + 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, 1280, 1952, 1984, 2016, + /* 2x-4x */ + 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_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 = tableSize - 1; + return CVI_SUCCESS; + } + + for (CVI_U32 i = 1; i < tableSize; 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 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 u16Mode = g_au16SC1346_1L_GainMode[ViPipe]; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + struct gain_tbl_info_s *info; + CVI_S32 i = 0, tbl_num = 0; + + SC1346_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 */ + + /* Again. */ + 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[WDR_AGAIN2_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR_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[WDR_DGAIN2_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR_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[WDR_AGAIN1_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR_AGAIN1_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[WDR_DGAIN1_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR_DGAIN1_1_ADDR].u32Data = (u32Dgain & 0xFF); + + pstSnsRegsInfo->astI2cData[WDR_DGAIN2_0_ADDR].u8DelayFrmNum = 1; + pstSnsRegsInfo->astI2cData[WDR_DGAIN2_1_ADDR].u8DelayFrmNum = 1; + pstSnsRegsInfo->astI2cData[WDR_AGAIN2_0_ADDR].u8DelayFrmNum = 1; + pstSnsRegsInfo->astI2cData[WDR_AGAIN2_1_ADDR].u8DelayFrmNum = 1; + } else if (u16Mode == SNS_GAIN_MODE_SHARE) { + /* Again. */ + 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[WDR_AGAIN1_0_ADDR].u32Data = (info->regGain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_AGAIN2_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR_AGAIN1_1_ADDR].u32Data = (u32Again & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_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[WDR_DGAIN1_0_ADDR].u32Data = (info->regGain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_DGAIN2_0_ADDR].u32Data = (info->regGain & 0xFF); + u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[WDR_DGAIN1_1_ADDR].u32Data = (u32Dgain & 0xFF); + pstSnsRegsInfo->astI2cData[WDR_DGAIN2_1_ADDR].u32Data = (u32Dgain & 0xFF); + + pstSnsRegsInfo->astI2cData[WDR_DGAIN2_0_ADDR].u8DelayFrmNum = 1; + pstSnsRegsInfo->astI2cData[WDR_DGAIN2_1_ADDR].u8DelayFrmNum = 1; + pstSnsRegsInfo->astI2cData[WDR_AGAIN2_0_ADDR].u8DelayFrmNum = 1; + pstSnsRegsInfo->astI2cData[WDR_AGAIN2_1_ADDR].u8DelayFrmNum = 1; + } + } + 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 = 1; + 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); + SC1346_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32IntTimeMaxTmp = ((pstSnsState->au32FL[0] - 6) * 0x40) / (au32Ratio[0] + 0x40) / 4 * 4; + u32IntTimeMaxTmp = (u32IntTimeMaxTmp > (g_astSC1346_1L_State[ViPipe].u32Sexp_MAX)) ? + (g_astSC1346_1L_State[ViPipe].u32Sexp_MAX) : u32IntTimeMaxTmp; + u32IntTimeMaxTmp = (!u32IntTimeMaxTmp) ? u32ShortTimeMinLimit : u32IntTimeMaxTmp; + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + /* [TODO] Convert to 1-line unit */ + u32IntTimeMaxTmp = u32IntTimeMaxTmp / 2; + u32ShortTimeMinLimit = (u32ShortTimeMinLimit + 1) / 2; + au32IntTimeMax[0] = (pstSnsState->au32FL[0] - 6) / 5; + 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; + + 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 SC1346_1L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC1346_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC1346_1L_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; + + SC1346_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + if (pstSnsState->u8ImgMode == SC1346_1L_MODE_720P30_WDR) + pstSnsState->u8ImgMode = SC1346_1L_MODE_720P30; + else if (pstSnsState->u8ImgMode == SC1346_1L_MODE_720P60_WDR) + pstSnsState->u8ImgMode = SC1346_1L_MODE_720P60; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC1346_1L_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "linear mode\n"); + break; + case WDR_MODE_2To1_LINE: + if (pstSnsState->u8ImgMode == SC1346_1L_MODE_720P30) + pstSnsState->u8ImgMode = SC1346_1L_MODE_720P30_WDR; + else if (pstSnsState->u8ImgMode == SC1346_1L_MODE_720P60) + pstSnsState->u8ImgMode = SC1346_1L_MODE_720P60_WDR; + pstSnsState->enWDRMode = WDR_MODE_2To1_LINE; + pstSnsState->u32FLStd = g_astSC1346_1L_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "2to1 line WDR 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); + SC1346_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_aunSC1346_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 = sc1346_1L_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc1346_1L_addr_byte; + pstI2c_data[i].u32DataByteNum = sc1346_1L_data_byte; + } + + //DOL 2t1 Mode Regs + switch (pstSnsState->enWDRMode) { + case WDR_MODE_2To1_LINE: + pstI2c_data[WDR_SHS1_0_ADDR].u32RegAddr = SC1346_1L_SHS1_0_ADDR; + pstI2c_data[WDR_SHS1_1_ADDR].u32RegAddr = SC1346_1L_SHS1_1_ADDR; + pstI2c_data[WDR_SHS1_2_ADDR].u32RegAddr = SC1346_1L_SHS1_2_ADDR; + pstI2c_data[WDR_SHS2_0_ADDR].u32RegAddr = SC1346_1L_SHS1_0_ADDR; + pstI2c_data[WDR_SHS2_1_ADDR].u32RegAddr = SC1346_1L_SHS1_1_ADDR; + pstI2c_data[WDR_SHS2_2_ADDR].u32RegAddr = SC1346_1L_SHS1_2_ADDR; + pstI2c_data[WDR_AGAIN1_0_ADDR].u32RegAddr = SC1346_1L_AGAIN_ADDR; + pstI2c_data[WDR_AGAIN1_1_ADDR].u32RegAddr = SC1346_1L_DGAIN0_ADDR + 1; + pstI2c_data[WDR_AGAIN2_0_ADDR].u32RegAddr = SC1346_1L_AGAIN_ADDR; + pstI2c_data[WDR_AGAIN2_1_ADDR].u32RegAddr = SC1346_1L_DGAIN0_ADDR + 1; + pstI2c_data[WDR_DGAIN1_0_ADDR].u32RegAddr = SC1346_1L_DGAIN0_ADDR; + pstI2c_data[WDR_DGAIN1_1_ADDR].u32RegAddr = SC1346_1L_DGAIN0_ADDR + 1; + pstI2c_data[WDR_DGAIN2_0_ADDR].u32RegAddr = SC1346_1L_DGAIN0_ADDR; + pstI2c_data[WDR_DGAIN2_1_ADDR].u32RegAddr = SC1346_1L_DGAIN0_ADDR + 1; + pstI2c_data[WDR_VMAX_0_ADDR].u32RegAddr = SC1346_1L_VMAX_ADDR; + pstI2c_data[WDR_VMAX_1_ADDR].u32RegAddr = SC1346_1L_VMAX_ADDR + 1; + pstI2c_data[WDR_FLIP_MIRROR_ADDR].u32RegAddr = SC1346_1L_FLIP_MIRROR_ADDR; + break; + default: + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC1346_1L_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC1346_1L_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC1346_1L_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC1346_1L_AGAIN_ADDR; + pstI2c_data[LINEAR_AGAIN_1_ADDR].u32RegAddr = SC1346_1L_DGAIN0_ADDR + 1; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC1346_1L_DGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC1346_1L_DGAIN0_ADDR + 1; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC1346_1L_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC1346_1L_VMAX_ADDR + 1; + pstI2c_data[LINEAR_FLIP_MIRROR_ADDR].u32RegAddr = SC1346_1L_FLIP_MIRROR_ADDR; + 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; + } + + /* always update exposure time on wdr mode */ + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + if (i <= WDR_SHS2_2_ADDR) { + 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]; + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) + pstCfg0->snsCfg.astI2cData[WDR_FLIP_MIRROR_ADDR].bDropFrm = CVI_FALSE; + else + pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR_ADDR].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); + SC1346_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 (SC1346_1L_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC1346_1L_MODE_720P30; + } 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 (SC1346_1L_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC1346_1L_MODE_720P30_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 (pstSensorImageMode->f32Fps <= 60) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC1346_1L_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC1346_1L_MODE_720P60; + } 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 (SC1346_1L_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC1346_1L_MODE_720P60_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 sc1346_1L_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; + + SC1346_1L_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_aeSc1346_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; + } + + if (pstSnsState->enWDRMode == WDR_MODE_2To1_LINE) { + pstSnsRegsInfo->astI2cData[WDR_FLIP_MIRROR_ADDR].u32Data = value; + pstSnsRegsInfo->astI2cData[WDR_FLIP_MIRROR_ADDR].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[WDR_FLIP_MIRROR_ADDR].u8DropFrmNum = 1; + } else { + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR_ADDR].u32Data = value; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR_ADDR].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR_ADDR].u8DropFrmNum = 1; + } + g_aeSc1346_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC1346_1L_MODE_S *pstMode = CVI_NULL; + + SC1346_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC1346_1L_MODE_720P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC1346_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; + + SC1346_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc1346_1L_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC1346_1L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC1346_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 = &sc1346_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 = sc1346_1L_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc1346_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 sc1346_1L_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC1346_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; + + SC1346_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)); + + SC1346_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; + + SC1346_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC1346_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 = SC1346_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, SC1346_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, SC1346_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, SC1346_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_au16SC1346_1L_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC1346_1L_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC1346_1L_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc1346_1L_standby, + .pfnRestart = sc1346_1L_restart, + .pfnMirrorFlip = sc1346_1L_mirror_flip, + .pfnWriteReg = sc1346_1L_write_register, + .pfnReadReg = sc1346_1L_read_register, + .pfnSetBusInfo = sc1346_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 = sc1346_1L_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L/sc1346_1L_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L/sc1346_1L_cmos_ex.h new file mode 100644 index 00000000..6eab0d29 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L/sc1346_1L_cmos_ex.h @@ -0,0 +1,109 @@ +#ifndef __SC1346_1L_CMOS_EX_H_ +#define __SC1346_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 sc1346_1l_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_FLIP_MIRROR_ADDR, + LINEAR_REGS_NUM +}; + +enum sc1346_1l_dol2_regs_e { + WDR_SHS1_0_ADDR, + WDR_SHS1_1_ADDR, + WDR_SHS1_2_ADDR, + WDR_SHS2_0_ADDR, + WDR_SHS2_1_ADDR, + WDR_SHS2_2_ADDR, + WDR_AGAIN1_0_ADDR, + WDR_AGAIN1_1_ADDR, + WDR_AGAIN2_0_ADDR, + WDR_AGAIN2_1_ADDR, + WDR_DGAIN1_0_ADDR, + WDR_DGAIN1_1_ADDR, + WDR_DGAIN2_0_ADDR, + WDR_DGAIN2_1_ADDR, + WDR_VMAX_0_ADDR, + WDR_VMAX_1_ADDR, + WDR_FLIP_MIRROR_ADDR, + WDR_REGS_NUM +}; + +typedef enum _SC1346_1L_MODE_E { + SC1346_1L_MODE_720P30 = 0, + SC1346_1L_MODE_720P60, + SC1346_1L_MODE_LINEAR_NUM, + SC1346_1L_MODE_720P30_WDR = SC1346_1L_MODE_LINEAR_NUM, + SC1346_1L_MODE_720P60_WDR, + SC1346_1L_MODE_NUM +} SC1346_1L_MODE_E; + +typedef struct _SC1346_1L_STATE_S { + CVI_U32 u32Sexp_MAX; +} SC1346_1L_STATE_S; + +typedef struct _SC1346_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_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16SexpMaxReg; + char name[64]; +} SC1346_1L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC1346_1L[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC1346_1L_BusInfo[]; +extern CVI_U16 g_au16SC1346_1L_GainMode[]; +extern CVI_U16 g_au16SC1346_1L_L2SMode[]; +extern const CVI_U8 sc1346_1L_i2c_addr; +extern const CVI_U32 sc1346_1L_addr_byte; +extern const CVI_U32 sc1346_1L_data_byte; +extern void sc1346_1L_init(VI_PIPE ViPipe); +extern void sc1346_1L_exit(VI_PIPE ViPipe); +extern void sc1346_1L_standby(VI_PIPE ViPipe); +extern void sc1346_1L_restart(VI_PIPE ViPipe); +extern int sc1346_1L_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc1346_1L_read_register(VI_PIPE ViPipe, int addr); +extern int sc1346_1L_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC1346_1L_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L/sc1346_1L_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L/sc1346_1L_cmos_param.h new file mode 100644 index 00000000..33d7537a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L/sc1346_1L_cmos_param.h @@ -0,0 +1,246 @@ +#ifndef __SC1346_1L_CMOS_PARAM_H_ +#define __SC1346_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 "sc1346_1L_cmos_ex.h" + +static const SC1346_1L_MODE_S g_astSC1346_1L_mode[SC1346_1L_MODE_NUM] = { + [SC1346_1L_MODE_720P30] = { + .name = "720p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.37, /* 750 * 30 / 0x3FFF*/ + .u32HtsDef = 1280, + .u32VtsDef = 750, + .stExp[0] = { + .u16Min = 2, + .u16Max = 750 - 6, + .u16Def = 100, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 32768, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 4032, + .u16Def = 1024, + .u16Step = 1, + }, + }, + [SC1346_1L_MODE_720P30_WDR] = { + .name = "720p30wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.37, /* 750 * 30 / 0x3FFF*/ + .u32HtsDef = 1280, + .u32VtsDef = 750, + .u16SexpMaxReg = 0x13E, + }, + [SC1346_1L_MODE_720P60] = { + .name = "720p60", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + .f32MaxFps = 60, + .f32MinFps = 2.74, /* 750 * 60 / 0x3FFF*/ + .u32HtsDef = 1280, + .u32VtsDef = 750, + .stExp[0] = { + .u16Min = 2, + .u16Max = 750 - 6, + .u16Def = 100, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 32768, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 4032, + .u16Def = 1024, + .u16Step = 1, + }, + }, + [SC1346_1L_MODE_720P60_WDR] = { + .name = "720p60wdr", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + .astImg[1] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + .f32MaxFps = 60, + .f32MinFps = 1.37, /* 750 * 30 / 0x3FFF*/ + .u32HtsDef = 1280, + .u32VtsDef = 750, + .u16SexpMaxReg = 0x13E, + }, +}; + +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 + , 1092, 1092, 1092, 1092 + #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 + {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 sc1346_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, + .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 /* __SC1346_1L_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L/sc1346_1L_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L/sc1346_1L_sensor_ctl.c new file mode 100644 index 00000000..a459930f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L/sc1346_1L_sensor_ctl.c @@ -0,0 +1,464 @@ +#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 "sc1346_1L_cmos_ex.h" + +static void sc1346_1L_linear_720p30_init(VI_PIPE ViPipe); +static void sc1346_1L_linear_720p60_init(VI_PIPE ViPipe); + +const CVI_U8 sc1346_1L_i2c_addr = 0x30; /* I2C Address of SC1346_1L */ +const CVI_U32 sc1346_1L_addr_byte = 2; +const CVI_U32 sc1346_1L_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc1346_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_aunSC1346_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, sc1346_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 sc1346_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 sc1346_1L_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 (sc1346_1L_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc1346_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, sc1346_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 (sc1346_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 sc1346_1L_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 (sc1346_1L_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc1346_1L_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc1346_1L_addr_byte + sc1346_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 sc1346_1L_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) + sc1346_1L_write_register(ViPipe, addr, data); + } +} + +void sc1346_1L_standby(VI_PIPE ViPipe) +{ + sc1346_1L_write_register(ViPipe, 0x0100, 0x00); +} + +void sc1346_1L_restart(VI_PIPE ViPipe) +{ + sc1346_1L_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc1346_1L_write_register(ViPipe, 0x0100, 0x01); +} + +void sc1346_1L_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC1346_1L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc1346_1L_write_register(ViPipe, + g_pastSC1346_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC1346_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define SC1346_1L_CHIP_ID_HI_ADDR 0x3107 +#define SC1346_1L_CHIP_ID_LO_ADDR 0x3108 +#define SC1346_1L_CHIP_ID 0xda4d + +int sc1346_1L_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc1346_1L_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc1346_1L_read_register(ViPipe, SC1346_1L_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 = sc1346_1L_read_register(ViPipe, SC1346_1L_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 != SC1346_1L_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc1346_1L_init(VI_PIPE ViPipe) +{ + CVI_U8 u8ImgMode = g_pastSC1346_1L[ViPipe]->u8ImgMode; + + sc1346_1L_i2c_init(ViPipe); + + if ((u8ImgMode == SC1346_1L_MODE_720P30) || (u8ImgMode == SC1346_1L_MODE_720P30_WDR)) + sc1346_1L_linear_720p30_init(ViPipe); + else if ((u8ImgMode == SC1346_1L_MODE_720P60) || (u8ImgMode == SC1346_1L_MODE_720P60_WDR)) + sc1346_1L_linear_720p60_init(ViPipe); + + g_pastSC1346_1L[ViPipe]->bInit = CVI_TRUE; +} + +void sc1346_1L_exit(VI_PIPE ViPipe) +{ + sc1346_1L_i2c_exit(ViPipe); +} + +/* 720P30 */ +static void sc1346_1L_linear_720p30_init(VI_PIPE ViPipe) +{ + sc1346_1L_write_register(ViPipe, 0x0103, 0x01); + sc1346_1L_write_register(ViPipe, 0x0100, 0x00); + sc1346_1L_write_register(ViPipe, 0x36e9, 0x80); + sc1346_1L_write_register(ViPipe, 0x37f9, 0x80); + sc1346_1L_write_register(ViPipe, 0x301f, 0x01); + sc1346_1L_write_register(ViPipe, 0x3106, 0x05); + sc1346_1L_write_register(ViPipe, 0x3301, 0x06); + sc1346_1L_write_register(ViPipe, 0x3306, 0x50); + sc1346_1L_write_register(ViPipe, 0x3308, 0x0a); + sc1346_1L_write_register(ViPipe, 0x330a, 0x00); + sc1346_1L_write_register(ViPipe, 0x330b, 0xda); + sc1346_1L_write_register(ViPipe, 0x330e, 0x0a); + sc1346_1L_write_register(ViPipe, 0x331e, 0x61); + sc1346_1L_write_register(ViPipe, 0x331f, 0xa1); + sc1346_1L_write_register(ViPipe, 0x3364, 0x1f); + sc1346_1L_write_register(ViPipe, 0x3390, 0x09); + sc1346_1L_write_register(ViPipe, 0x3391, 0x0f); + sc1346_1L_write_register(ViPipe, 0x3392, 0x1f); + sc1346_1L_write_register(ViPipe, 0x3393, 0x30); + sc1346_1L_write_register(ViPipe, 0x3394, 0x30); + sc1346_1L_write_register(ViPipe, 0x3395, 0x30); + sc1346_1L_write_register(ViPipe, 0x33ad, 0x10); + sc1346_1L_write_register(ViPipe, 0x33b3, 0x40); + sc1346_1L_write_register(ViPipe, 0x33f9, 0x50); + sc1346_1L_write_register(ViPipe, 0x33fb, 0x80); + sc1346_1L_write_register(ViPipe, 0x33fc, 0x09); + sc1346_1L_write_register(ViPipe, 0x33fd, 0x0f); + sc1346_1L_write_register(ViPipe, 0x349f, 0x03); + sc1346_1L_write_register(ViPipe, 0x34a6, 0x09); + sc1346_1L_write_register(ViPipe, 0x34a7, 0x0f); + sc1346_1L_write_register(ViPipe, 0x34a8, 0x40); + sc1346_1L_write_register(ViPipe, 0x34a9, 0x30); + sc1346_1L_write_register(ViPipe, 0x34aa, 0x00); + sc1346_1L_write_register(ViPipe, 0x34ab, 0xe8); + sc1346_1L_write_register(ViPipe, 0x34ac, 0x01); + sc1346_1L_write_register(ViPipe, 0x34ad, 0x0c); + sc1346_1L_write_register(ViPipe, 0x3630, 0xe2); + sc1346_1L_write_register(ViPipe, 0x3632, 0x76); + sc1346_1L_write_register(ViPipe, 0x3633, 0x33); + sc1346_1L_write_register(ViPipe, 0x3639, 0xf4); + sc1346_1L_write_register(ViPipe, 0x3641, 0x00); + sc1346_1L_write_register(ViPipe, 0x3670, 0x09); + sc1346_1L_write_register(ViPipe, 0x3674, 0xe2); + sc1346_1L_write_register(ViPipe, 0x3675, 0xea); + sc1346_1L_write_register(ViPipe, 0x3676, 0xea); + sc1346_1L_write_register(ViPipe, 0x367c, 0x09); + sc1346_1L_write_register(ViPipe, 0x367d, 0x0f); + sc1346_1L_write_register(ViPipe, 0x3690, 0x22); + sc1346_1L_write_register(ViPipe, 0x3691, 0x22); + sc1346_1L_write_register(ViPipe, 0x3692, 0x22); + sc1346_1L_write_register(ViPipe, 0x3698, 0x88); + sc1346_1L_write_register(ViPipe, 0x3699, 0x90); + sc1346_1L_write_register(ViPipe, 0x369a, 0xa1); + sc1346_1L_write_register(ViPipe, 0x369b, 0xc3); + sc1346_1L_write_register(ViPipe, 0x369c, 0x09); + sc1346_1L_write_register(ViPipe, 0x369d, 0x0f); + sc1346_1L_write_register(ViPipe, 0x36a2, 0x09); + sc1346_1L_write_register(ViPipe, 0x36a3, 0x0b); + sc1346_1L_write_register(ViPipe, 0x36a4, 0x0f); + sc1346_1L_write_register(ViPipe, 0x36d0, 0x01); + sc1346_1L_write_register(ViPipe, 0x370f, 0x01); + sc1346_1L_write_register(ViPipe, 0x3722, 0x41); + sc1346_1L_write_register(ViPipe, 0x3724, 0x41); + sc1346_1L_write_register(ViPipe, 0x3725, 0xc1); + sc1346_1L_write_register(ViPipe, 0x3728, 0x00); + sc1346_1L_write_register(ViPipe, 0x37b0, 0x41); + sc1346_1L_write_register(ViPipe, 0x37b1, 0x41); + sc1346_1L_write_register(ViPipe, 0x37b2, 0x47); + sc1346_1L_write_register(ViPipe, 0x37b3, 0x09); + sc1346_1L_write_register(ViPipe, 0x37b4, 0x0f); + sc1346_1L_write_register(ViPipe, 0x3903, 0x40); + sc1346_1L_write_register(ViPipe, 0x3904, 0x04); + sc1346_1L_write_register(ViPipe, 0x3905, 0x8d); + sc1346_1L_write_register(ViPipe, 0x3907, 0x00); + sc1346_1L_write_register(ViPipe, 0x3908, 0x41); + sc1346_1L_write_register(ViPipe, 0x391f, 0x41); + sc1346_1L_write_register(ViPipe, 0x3933, 0x80); + sc1346_1L_write_register(ViPipe, 0x3934, 0x02); + sc1346_1L_write_register(ViPipe, 0x3937, 0x74); + sc1346_1L_write_register(ViPipe, 0x3939, 0x0f); + sc1346_1L_write_register(ViPipe, 0x393a, 0xd4); + sc1346_1L_write_register(ViPipe, 0x3e01, 0x2e); + sc1346_1L_write_register(ViPipe, 0x3e02, 0xa0); + sc1346_1L_write_register(ViPipe, 0x440e, 0x02); + sc1346_1L_write_register(ViPipe, 0x4509, 0x20); + sc1346_1L_write_register(ViPipe, 0x450d, 0x28); + sc1346_1L_write_register(ViPipe, 0x5780, 0x66); + sc1346_1L_write_register(ViPipe, 0x578d, 0x40); + sc1346_1L_write_register(ViPipe, 0x36e9, 0x20); + sc1346_1L_write_register(ViPipe, 0x37f9, 0x20); + sc1346_1L_write_register(ViPipe, 0x0100, 0x01); + + sc1346_1L_default_reg_init(ViPipe); + + sc1346_1L_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC1346_1L 720P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +/* 720P60 */ +static void sc1346_1L_linear_720p60_init(VI_PIPE ViPipe) +{ + sc1346_1L_write_register(ViPipe, 0x0103, 0x01); + sc1346_1L_write_register(ViPipe, 0x0100, 0x00); + sc1346_1L_write_register(ViPipe, 0x36e9, 0x80); + sc1346_1L_write_register(ViPipe, 0x37f9, 0x80); + sc1346_1L_write_register(ViPipe, 0x301f, 0x02); + sc1346_1L_write_register(ViPipe, 0x3106, 0x05); + sc1346_1L_write_register(ViPipe, 0x3301, 0x0b); + sc1346_1L_write_register(ViPipe, 0x3303, 0x10); + sc1346_1L_write_register(ViPipe, 0x3306, 0x50); + sc1346_1L_write_register(ViPipe, 0x3308, 0x0a); + sc1346_1L_write_register(ViPipe, 0x330a, 0x00); + sc1346_1L_write_register(ViPipe, 0x330b, 0xda); + sc1346_1L_write_register(ViPipe, 0x330e, 0x0a); + sc1346_1L_write_register(ViPipe, 0x331e, 0x61); + sc1346_1L_write_register(ViPipe, 0x331f, 0xa1); + sc1346_1L_write_register(ViPipe, 0x3320, 0x04); + sc1346_1L_write_register(ViPipe, 0x3327, 0x08); + sc1346_1L_write_register(ViPipe, 0x3329, 0x09); + sc1346_1L_write_register(ViPipe, 0x3364, 0x1f); + sc1346_1L_write_register(ViPipe, 0x3390, 0x09); + sc1346_1L_write_register(ViPipe, 0x3391, 0x0f); + sc1346_1L_write_register(ViPipe, 0x3392, 0x1f); + sc1346_1L_write_register(ViPipe, 0x3393, 0x30); + sc1346_1L_write_register(ViPipe, 0x3394, 0xff); + sc1346_1L_write_register(ViPipe, 0x3395, 0xff); + sc1346_1L_write_register(ViPipe, 0x33ad, 0x10); + sc1346_1L_write_register(ViPipe, 0x33b3, 0x40); + sc1346_1L_write_register(ViPipe, 0x33f9, 0x50); + sc1346_1L_write_register(ViPipe, 0x33fb, 0x80); + sc1346_1L_write_register(ViPipe, 0x33fc, 0x09); + sc1346_1L_write_register(ViPipe, 0x33fd, 0x0f); + sc1346_1L_write_register(ViPipe, 0x349f, 0x03); + sc1346_1L_write_register(ViPipe, 0x34a6, 0x09); + sc1346_1L_write_register(ViPipe, 0x34a7, 0x0f); + sc1346_1L_write_register(ViPipe, 0x34a8, 0x40); + sc1346_1L_write_register(ViPipe, 0x34a9, 0x30); + sc1346_1L_write_register(ViPipe, 0x34aa, 0x00); + sc1346_1L_write_register(ViPipe, 0x34ab, 0xe8); + sc1346_1L_write_register(ViPipe, 0x34ac, 0x01); + sc1346_1L_write_register(ViPipe, 0x34ad, 0x0c); + sc1346_1L_write_register(ViPipe, 0x3630, 0xe2); + sc1346_1L_write_register(ViPipe, 0x3632, 0x76); + sc1346_1L_write_register(ViPipe, 0x3633, 0x33); + sc1346_1L_write_register(ViPipe, 0x3639, 0xf4); + sc1346_1L_write_register(ViPipe, 0x3641, 0x28); + sc1346_1L_write_register(ViPipe, 0x3670, 0x09); + sc1346_1L_write_register(ViPipe, 0x3674, 0xe2); + sc1346_1L_write_register(ViPipe, 0x3675, 0xea); + sc1346_1L_write_register(ViPipe, 0x3676, 0xea); + sc1346_1L_write_register(ViPipe, 0x367c, 0x09); + sc1346_1L_write_register(ViPipe, 0x367d, 0x0f); + sc1346_1L_write_register(ViPipe, 0x3690, 0x22); + sc1346_1L_write_register(ViPipe, 0x3691, 0x22); + sc1346_1L_write_register(ViPipe, 0x3692, 0x32); + sc1346_1L_write_register(ViPipe, 0x3698, 0x88); + sc1346_1L_write_register(ViPipe, 0x3699, 0x8f); + sc1346_1L_write_register(ViPipe, 0x369a, 0xa0); + sc1346_1L_write_register(ViPipe, 0x369b, 0xd1); + sc1346_1L_write_register(ViPipe, 0x369c, 0x09); + sc1346_1L_write_register(ViPipe, 0x369d, 0x0f); + sc1346_1L_write_register(ViPipe, 0x36a2, 0x09); + sc1346_1L_write_register(ViPipe, 0x36a3, 0x0b); + sc1346_1L_write_register(ViPipe, 0x36a4, 0x0f); + sc1346_1L_write_register(ViPipe, 0x36d0, 0x01); + sc1346_1L_write_register(ViPipe, 0x36eb, 0x05); + sc1346_1L_write_register(ViPipe, 0x36ec, 0x05); + sc1346_1L_write_register(ViPipe, 0x370f, 0x01); + sc1346_1L_write_register(ViPipe, 0x3722, 0x41); + sc1346_1L_write_register(ViPipe, 0x3724, 0x41); + sc1346_1L_write_register(ViPipe, 0x3725, 0xc1); + sc1346_1L_write_register(ViPipe, 0x3727, 0x14); + sc1346_1L_write_register(ViPipe, 0x3728, 0x00); + sc1346_1L_write_register(ViPipe, 0x37b0, 0x21); + sc1346_1L_write_register(ViPipe, 0x37b1, 0x21); + sc1346_1L_write_register(ViPipe, 0x37b2, 0x37); + sc1346_1L_write_register(ViPipe, 0x37b3, 0x09); + sc1346_1L_write_register(ViPipe, 0x37b4, 0x0f); + sc1346_1L_write_register(ViPipe, 0x37fb, 0x31); + sc1346_1L_write_register(ViPipe, 0x37fc, 0x01); + sc1346_1L_write_register(ViPipe, 0x3903, 0x40); + sc1346_1L_write_register(ViPipe, 0x3904, 0x04); + sc1346_1L_write_register(ViPipe, 0x3905, 0x8d); + sc1346_1L_write_register(ViPipe, 0x3907, 0x00); + sc1346_1L_write_register(ViPipe, 0x3908, 0x41); + sc1346_1L_write_register(ViPipe, 0x391f, 0x41); + sc1346_1L_write_register(ViPipe, 0x3933, 0x80); + sc1346_1L_write_register(ViPipe, 0x3934, 0x0a); + sc1346_1L_write_register(ViPipe, 0x3935, 0x01); + sc1346_1L_write_register(ViPipe, 0x3936, 0x55); + sc1346_1L_write_register(ViPipe, 0x3937, 0x71); + sc1346_1L_write_register(ViPipe, 0x3938, 0x72); + sc1346_1L_write_register(ViPipe, 0x3939, 0x0f); + sc1346_1L_write_register(ViPipe, 0x393a, 0xef); + sc1346_1L_write_register(ViPipe, 0x393b, 0x0f); + sc1346_1L_write_register(ViPipe, 0x393c, 0xcd); + sc1346_1L_write_register(ViPipe, 0x3e01, 0x2e); + sc1346_1L_write_register(ViPipe, 0x3e02, 0x80); + sc1346_1L_write_register(ViPipe, 0x440e, 0x02); + sc1346_1L_write_register(ViPipe, 0x4509, 0x25); + sc1346_1L_write_register(ViPipe, 0x450d, 0x28); + sc1346_1L_write_register(ViPipe, 0x4819, 0x09); + sc1346_1L_write_register(ViPipe, 0x481b, 0x05); + sc1346_1L_write_register(ViPipe, 0x481d, 0x14); + sc1346_1L_write_register(ViPipe, 0x481f, 0x04); + sc1346_1L_write_register(ViPipe, 0x4821, 0x0a); + sc1346_1L_write_register(ViPipe, 0x4823, 0x05); + sc1346_1L_write_register(ViPipe, 0x4825, 0x04); + sc1346_1L_write_register(ViPipe, 0x4827, 0x05); + sc1346_1L_write_register(ViPipe, 0x4829, 0x08); + sc1346_1L_write_register(ViPipe, 0x5780, 0x66); + sc1346_1L_write_register(ViPipe, 0x578d, 0x40); + sc1346_1L_write_register(ViPipe, 0x36e9, 0x20); + sc1346_1L_write_register(ViPipe, 0x37f9, 0x20); + sc1346_1L_write_register(ViPipe, 0x0100, 0x01); + + sc1346_1L_default_reg_init(ViPipe); + + sc1346_1L_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC1346_1L 720P 60fps 10bit LINE Init OK!===\n", ViPipe); + +} \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L_slave/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L_slave/Makefile new file mode 100644 index 00000000..41bc2c0f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L_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_sc1346_1l_slave.a +TARGET_SO = $(MW_LIB)/libsns_sc1346_1l_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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L_slave/sc1346_1L_slave_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L_slave/sc1346_1L_slave_cmos.c new file mode 100644 index 00000000..3bef5bc0 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L_slave/sc1346_1L_slave_cmos.c @@ -0,0 +1,1027 @@ +#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 "sc1346_1L_slave_cmos_ex.h" +#include "sc1346_1L_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 SC1346_1L_SLAVE_ID 35 +#define SENSOR_SC1346_1L_SLAVE_WIDTH 1280 +#define SENSOR_SC1346_1L_SLAVE_HEIGHT 720 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC1346_1L_Slave[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC1346_1L_SLAVE_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC1346_1L_Slave[dev]) +#define SC1346_1L_SLAVE_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC1346_1L_Slave[dev] = pstCtx) +#define SC1346_1L_SLAVE_SENSOR_RESET_CTX(dev) (g_pastSC1346_1L_Slave[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC1346_1L_Slave_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC1346_1L_Slave_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC1346_1L_Slave_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +SC1346_1L_SLAVE_STATE_S g_astSC1346_1L_Slave_State[VI_MAX_PIPE_NUM] = {{0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc1346_Slave_MirrorFip[VI_MAX_PIPE_NUM] = {ISP_SNS_NORMAL}; +/**************************************************************************** + * 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); +/*****SC1346_1L_SLAVE Lines Range*****/ +#define SC1346_1L_SLAVE_FULL_LINES_MAX (0x3FFF) + +/*****SC1346_1L_SLAVE Register Address*****/ +#define SC1346_1L_SLAVE_SHS1_0_ADDR 0x3E00 +#define SC1346_1L_SLAVE_SHS1_1_ADDR 0x3E01 +#define SC1346_1L_SLAVE_SHS1_2_ADDR 0x3E02 +#define SC1346_1L_SLAVE_AGAIN_ADDR 0x3E09 +#define SC1346_1L_SLAVE_DGAIN0_ADDR 0x3E06 +#define SC1346_1L_SLAVE_VMAX_ADDR 0x320E +#define SC1346_1L_SLAVE_FLIP_MIRROR_ADDR 0x3221 +#define SC1346_1L_SLAVE_TABLE_END 0xFFFF + +#define SC1346_1L_SLAVE_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 SC1346_1L_SLAVE_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 fps = 30; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC1346_1L_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC1346_1L_Slave_mode[pstSnsState->u8ImgMode]; + if (pstSnsState->u8ImgMode == SC1346_1L_SLAVE_MODE_720P60) + fps = 60; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC1346_1L_SLAVE_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_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 * fps / 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); + SC1346_1L_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC1346_1L_Slave_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC1346_1L_Slave_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC1346_1L_Slave_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC1346_1L_SLAVE_MODE_720P30: + case SC1346_1L_SLAVE_MODE_720P60: + 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 > SC1346_1L_SLAVE_FULL_LINES_MAX) ? SC1346_1L_SLAVE_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; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC1346_1L_SLAVE_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) { + /* linear exposure reg range: + * min : 2 + * max : (vts - 6) + * step : 1 + */ + + u32MinTime = 2; + u32MaxTime = pstSnsState->au32FL[0] - 6; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : 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[] = { + { + .gainMax = 2016, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x08, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 8064, + .idxBase = 64, + .regGain = 0x09, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 16128, + .idxBase = 96, + .regGain = 0x0b, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 32256, + .idxBase = 128, + .regGain = 0x0f, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 32768, + .idxBase = 160, + .regGain = 0x1F, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, +}; + +static CVI_U32 Again_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, 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, + + 32768, +}; + +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, + }, +}; + +static CVI_U32 Dgain_table[] = { + /* 1x-2x */ + 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, 1280, 1952, 1984, 2016, + /* 2x-4x */ + 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_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 = tableSize - 1; + return CVI_SUCCESS; + } + + for (CVI_U32 i = 1; i < tableSize; 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 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; + + SC1346_1L_SLAVE_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. */ + 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); + } + 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 SC1346_1L_SLAVE_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC1346_1L_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC1346_1L_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; + + SC1346_1L_SLAVE_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_astSC1346_1L_Slave_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); + SC1346_1L_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_aunSC1346_1L_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 = sc1346_1L_slave_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc1346_1L_slave_addr_byte; + pstI2c_data[i].u32DataByteNum = sc1346_1L_slave_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 = SC1346_1L_SLAVE_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC1346_1L_SLAVE_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC1346_1L_SLAVE_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC1346_1L_SLAVE_AGAIN_ADDR; + pstI2c_data[LINEAR_AGAIN_1_ADDR].u32RegAddr = SC1346_1L_SLAVE_DGAIN0_ADDR + 1; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC1346_1L_SLAVE_DGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC1346_1L_SLAVE_DGAIN0_ADDR + 1; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC1346_1L_SLAVE_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC1346_1L_SLAVE_VMAX_ADDR + 1; + pstI2c_data[LINEAR_FLIP_MIRROR_ADDR].u32RegAddr = SC1346_1L_SLAVE_FLIP_MIRROR_ADDR; + + 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]; + pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR_ADDR].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); + SC1346_1L_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 (SC1346_1L_SLAVE_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC1346_1L_SLAVE_MODE_720P30; + } 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) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (SC1346_1L_SLAVE_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC1346_1L_SLAVE_MODE_720P60; + } 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 sc1346_1L_slave_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; + + SC1346_1L_SLAVE_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_aeSc1346_Slave_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_ADDR].u32Data = value; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR_ADDR].bDropFrm = 1; + pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR_ADDR].u8DropFrmNum = 1; + g_aeSc1346_Slave_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC1346_1L_SLAVE_MODE_S *pstMode = CVI_NULL; + + SC1346_1L_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC1346_1L_SLAVE_MODE_720P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC1346_1L_Slave_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; + + SC1346_1L_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc1346_1L_slave_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC1346_1L_Slave_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC1346_1L_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 = &sc1346_1L_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 = sc1346_1L_slave_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc1346_1L_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 sc1346_1L_slave_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC1346_1L_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; + + SC1346_1L_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)); + + SC1346_1L_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; + + SC1346_1L_SLAVE_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC1346_1L_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 = SC1346_1L_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, SC1346_1L_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, SC1346_1L_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, SC1346_1L_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_au16SC1346_1L_Slave_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC1346_1L_Slave_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC1346_1L_Slave_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc1346_1L_slave_standby, + .pfnRestart = sc1346_1L_slave_restart, + .pfnMirrorFlip = sc1346_1L_slave_mirror_flip, + .pfnWriteReg = sc1346_1L_slave_write_register, + .pfnReadReg = sc1346_1L_slave_read_register, + .pfnSetBusInfo = sc1346_1L_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 = sc1346_1L_slave_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L_slave/sc1346_1L_slave_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L_slave/sc1346_1L_slave_cmos_ex.h new file mode 100644 index 00000000..50812dd8 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L_slave/sc1346_1L_slave_cmos_ex.h @@ -0,0 +1,87 @@ +#ifndef __SC1346_1L_SLAVE_CMOS_EX_H_ +#define __SC1346_1L_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 sc1346_1L_slave_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_FLIP_MIRROR_ADDR, + LINEAR_REGS_NUM +}; + + +typedef enum _SC1346_1L_SLAVE_MODE_E { + SC1346_1L_SLAVE_MODE_720P30 = 0, + SC1346_1L_SLAVE_MODE_720P60, + SC1346_1L_SLAVE_MODE_LINEAR_NUM, + SC1346_1L_SLAVE_MODE_NUM +} SC1346_1L_SLAVE_MODE_E; + +typedef struct _SC1346_1L_SLAVE_STATE_S { + CVI_U32 u32Sexp_MAX; +} SC1346_1L_SLAVE_STATE_S; + +typedef struct _SC1346_1L_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 u16SexpMaxReg; + char name[64]; +} SC1346_1L_SLAVE_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC1346_1L_Slave[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC1346_1L_Slave_BusInfo[]; +extern CVI_U16 g_au16SC1346_1L_Slave_GainMode[]; +extern CVI_U16 g_au16SC1346_1L_Slave_L2SMode[]; +extern const CVI_U8 sc1346_1L_slave_i2c_addr; +extern const CVI_U32 sc1346_1L_slave_addr_byte; +extern const CVI_U32 sc1346_1L_slave_data_byte; +extern void sc1346_1L_slave_init(VI_PIPE ViPipe); +extern void sc1346_1L_slave_exit(VI_PIPE ViPipe); +extern void sc1346_1L_slave_standby(VI_PIPE ViPipe); +extern void sc1346_1L_slave_restart(VI_PIPE ViPipe); +extern int sc1346_1L_slave_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc1346_1L_slave_read_register(VI_PIPE ViPipe, int addr); +extern int sc1346_1L_slave_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC1346_1L_SLAVE_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L_slave/sc1346_1L_slave_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L_slave/sc1346_1L_slave_cmos_param.h new file mode 100644 index 00000000..ac785d13 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L_slave/sc1346_1L_slave_cmos_param.h @@ -0,0 +1,166 @@ +#ifndef __SC1346_1L_SLAVE_CMOS_PARAM_H_ +#define __SC1346_1L_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 "sc1346_1L_slave_cmos_ex.h" + +static const SC1346_1L_SLAVE_MODE_S g_astSC1346_1L_Slave_mode[SC1346_1L_SLAVE_MODE_NUM] = { + [SC1346_1L_SLAVE_MODE_720P30] = { + .name = "720p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.37, /* 750 * 30 / 0x3FFF*/ + .u32HtsDef = 1280, + .u32VtsDef = 750, + .stExp[0] = { + .u16Min = 2, + .u16Max = 750 - 6, + .u16Def = 100, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 32768, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 4032, + .u16Def = 1024, + .u16Step = 1, + }, + }, + [SC1346_1L_SLAVE_MODE_720P60] = { + .name = "720p60", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + .f32MaxFps = 60, + .f32MinFps = 2.74, /* 750 * 60 / 0x3FFF*/ + .u32HtsDef = 1280, + .u32VtsDef = 750, + .stExp[0] = { + .u16Min = 2, + .u16Max = 750 - 6, + .u16Def = 100, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 32768, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 4032, + .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 + , 1092, 1092, 1092, 1092 + #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 + {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 sc1346_1L_slave_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 /* __SC1346_1L_SLAVE_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L_slave/sc1346_1L_slave_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L_slave/sc1346_1L_slave_sensor_ctl.c new file mode 100644 index 00000000..ebdae28a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc1346_1L_slave/sc1346_1L_slave_sensor_ctl.c @@ -0,0 +1,487 @@ +#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 "sc1346_1L_slave_cmos_ex.h" + +static void sc1346_1L_slave_linear_720p30_init(VI_PIPE ViPipe); +static void sc1346_1L_slave_linear_720p60_init(VI_PIPE ViPipe); + +const CVI_U8 sc1346_1L_slave_i2c_addr = 0x30; /* I2C Address of SC1346_1L_SLAVE */ +const CVI_U32 sc1346_1L_slave_addr_byte = 2; +const CVI_U32 sc1346_1L_slave_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc1346_1L_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_aunSC1346_1L_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/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc1346_1L_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 sc1346_1L_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 sc1346_1L_slave_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 (sc1346_1L_slave_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc1346_1L_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, sc1346_1L_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 (sc1346_1L_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 sc1346_1L_slave_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 (sc1346_1L_slave_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc1346_1L_slave_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc1346_1L_slave_addr_byte + sc1346_1L_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 sc1346_1L_slave_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) + sc1346_1L_slave_write_register(ViPipe, addr, data); + } +} + +void sc1346_1L_slave_standby(VI_PIPE ViPipe) +{ + sc1346_1L_slave_write_register(ViPipe, 0x0100, 0x00); +} + +void sc1346_1L_slave_restart(VI_PIPE ViPipe) +{ + sc1346_1L_slave_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc1346_1L_slave_write_register(ViPipe, 0x0100, 0x01); +} + +void sc1346_1L_slave_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC1346_1L_Slave[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc1346_1L_slave_write_register(ViPipe, + g_pastSC1346_1L_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC1346_1L_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define SC1346_1L_SLAVE_CHIP_ID_HI_ADDR 0x3107 +#define SC1346_1L_SLAVE_CHIP_ID_LO_ADDR 0x3108 +#define SC1346_1L_SLAVE_CHIP_ID 0xda4d + +int sc1346_1L_slave_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc1346_1L_slave_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc1346_1L_slave_read_register(ViPipe, SC1346_1L_SLAVE_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 = sc1346_1L_slave_read_register(ViPipe, SC1346_1L_SLAVE_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 != SC1346_1L_SLAVE_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc1346_1L_slave_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + CVI_U8 u8ImgMode; + + bInit = g_pastSC1346_1L_Slave[ViPipe]->bInit; + enWDRMode = g_pastSC1346_1L_Slave[ViPipe]->enWDRMode; + u8ImgMode = g_pastSC1346_1L_Slave[ViPipe]->u8ImgMode; + + sc1346_1L_slave_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_NONE) { + if (u8ImgMode == SC1346_1L_SLAVE_MODE_720P30) + sc1346_1L_slave_linear_720p30_init(ViPipe); + else if (u8ImgMode == SC1346_1L_SLAVE_MODE_720P60) + sc1346_1L_slave_linear_720p60_init(ViPipe); + else { + } + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_NONE) { + if (u8ImgMode == SC1346_1L_SLAVE_MODE_720P30) + sc1346_1L_slave_linear_720p30_init(ViPipe); + else if (u8ImgMode == SC1346_1L_SLAVE_MODE_720P60) + sc1346_1L_slave_linear_720p60_init(ViPipe); + else { + } + } + } + g_pastSC1346_1L_Slave[ViPipe]->bInit = CVI_TRUE; +} + +void sc1346_1L_slave_exit(VI_PIPE ViPipe) +{ + sc1346_1L_slave_i2c_exit(ViPipe); +} + +/* 720P30 */ +static void sc1346_1L_slave_linear_720p30_init(VI_PIPE ViPipe) +{ + sc1346_1L_slave_write_register(ViPipe, 0x0103, 0x01); + sc1346_1L_slave_write_register(ViPipe, 0x0100, 0x00); + sc1346_1L_slave_write_register(ViPipe, 0x36e9, 0x80); + sc1346_1L_slave_write_register(ViPipe, 0x37f9, 0x80); + sc1346_1L_slave_write_register(ViPipe, 0x301f, 0x01); + sc1346_1L_slave_write_register(ViPipe, 0x3106, 0x05); + sc1346_1L_slave_write_register(ViPipe, 0x3301, 0x06); + sc1346_1L_slave_write_register(ViPipe, 0x3306, 0x50); + sc1346_1L_slave_write_register(ViPipe, 0x3308, 0x0a); + sc1346_1L_slave_write_register(ViPipe, 0x330a, 0x00); + sc1346_1L_slave_write_register(ViPipe, 0x330b, 0xda); + sc1346_1L_slave_write_register(ViPipe, 0x330e, 0x0a); + sc1346_1L_slave_write_register(ViPipe, 0x331e, 0x61); + sc1346_1L_slave_write_register(ViPipe, 0x331f, 0xa1); + sc1346_1L_slave_write_register(ViPipe, 0x3364, 0x1f); + sc1346_1L_slave_write_register(ViPipe, 0x3390, 0x09); + sc1346_1L_slave_write_register(ViPipe, 0x3391, 0x0f); + sc1346_1L_slave_write_register(ViPipe, 0x3392, 0x1f); + sc1346_1L_slave_write_register(ViPipe, 0x3393, 0x30); + sc1346_1L_slave_write_register(ViPipe, 0x3394, 0x30); + sc1346_1L_slave_write_register(ViPipe, 0x3395, 0x30); + sc1346_1L_slave_write_register(ViPipe, 0x33ad, 0x10); + sc1346_1L_slave_write_register(ViPipe, 0x33b3, 0x40); + sc1346_1L_slave_write_register(ViPipe, 0x33f9, 0x50); + sc1346_1L_slave_write_register(ViPipe, 0x33fb, 0x80); + sc1346_1L_slave_write_register(ViPipe, 0x33fc, 0x09); + sc1346_1L_slave_write_register(ViPipe, 0x33fd, 0x0f); + sc1346_1L_slave_write_register(ViPipe, 0x349f, 0x03); + sc1346_1L_slave_write_register(ViPipe, 0x34a6, 0x09); + sc1346_1L_slave_write_register(ViPipe, 0x34a7, 0x0f); + sc1346_1L_slave_write_register(ViPipe, 0x34a8, 0x40); + sc1346_1L_slave_write_register(ViPipe, 0x34a9, 0x30); + sc1346_1L_slave_write_register(ViPipe, 0x34aa, 0x00); + sc1346_1L_slave_write_register(ViPipe, 0x34ab, 0xe8); + sc1346_1L_slave_write_register(ViPipe, 0x34ac, 0x01); + sc1346_1L_slave_write_register(ViPipe, 0x34ad, 0x0c); + sc1346_1L_slave_write_register(ViPipe, 0x3630, 0xe2); + sc1346_1L_slave_write_register(ViPipe, 0x3632, 0x76); + sc1346_1L_slave_write_register(ViPipe, 0x3633, 0x33); + sc1346_1L_slave_write_register(ViPipe, 0x3639, 0xf4); + sc1346_1L_slave_write_register(ViPipe, 0x3641, 0x00); + sc1346_1L_slave_write_register(ViPipe, 0x3670, 0x09); + sc1346_1L_slave_write_register(ViPipe, 0x3674, 0xe2); + sc1346_1L_slave_write_register(ViPipe, 0x3675, 0xea); + sc1346_1L_slave_write_register(ViPipe, 0x3676, 0xea); + sc1346_1L_slave_write_register(ViPipe, 0x367c, 0x09); + sc1346_1L_slave_write_register(ViPipe, 0x367d, 0x0f); + sc1346_1L_slave_write_register(ViPipe, 0x3690, 0x22); + sc1346_1L_slave_write_register(ViPipe, 0x3691, 0x22); + sc1346_1L_slave_write_register(ViPipe, 0x3692, 0x22); + sc1346_1L_slave_write_register(ViPipe, 0x3698, 0x88); + sc1346_1L_slave_write_register(ViPipe, 0x3699, 0x90); + sc1346_1L_slave_write_register(ViPipe, 0x369a, 0xa1); + sc1346_1L_slave_write_register(ViPipe, 0x369b, 0xc3); + sc1346_1L_slave_write_register(ViPipe, 0x369c, 0x09); + sc1346_1L_slave_write_register(ViPipe, 0x369d, 0x0f); + sc1346_1L_slave_write_register(ViPipe, 0x36a2, 0x09); + sc1346_1L_slave_write_register(ViPipe, 0x36a3, 0x0b); + sc1346_1L_slave_write_register(ViPipe, 0x36a4, 0x0f); + sc1346_1L_slave_write_register(ViPipe, 0x36d0, 0x01); + sc1346_1L_slave_write_register(ViPipe, 0x370f, 0x01); + sc1346_1L_slave_write_register(ViPipe, 0x3722, 0x41); + sc1346_1L_slave_write_register(ViPipe, 0x3724, 0x41); + sc1346_1L_slave_write_register(ViPipe, 0x3725, 0xc1); + sc1346_1L_slave_write_register(ViPipe, 0x3728, 0x00); + sc1346_1L_slave_write_register(ViPipe, 0x37b0, 0x41); + sc1346_1L_slave_write_register(ViPipe, 0x37b1, 0x41); + sc1346_1L_slave_write_register(ViPipe, 0x37b2, 0x47); + sc1346_1L_slave_write_register(ViPipe, 0x37b3, 0x09); + sc1346_1L_slave_write_register(ViPipe, 0x37b4, 0x0f); + sc1346_1L_slave_write_register(ViPipe, 0x3903, 0x40); + sc1346_1L_slave_write_register(ViPipe, 0x3904, 0x04); + sc1346_1L_slave_write_register(ViPipe, 0x3905, 0x8d); + sc1346_1L_slave_write_register(ViPipe, 0x3907, 0x00); + sc1346_1L_slave_write_register(ViPipe, 0x3908, 0x41); + sc1346_1L_slave_write_register(ViPipe, 0x391f, 0x41); + sc1346_1L_slave_write_register(ViPipe, 0x3933, 0x80); + sc1346_1L_slave_write_register(ViPipe, 0x3934, 0x02); + sc1346_1L_slave_write_register(ViPipe, 0x3937, 0x74); + sc1346_1L_slave_write_register(ViPipe, 0x3939, 0x0f); + sc1346_1L_slave_write_register(ViPipe, 0x393a, 0xd4); + sc1346_1L_slave_write_register(ViPipe, 0x3e01, 0x2e); + sc1346_1L_slave_write_register(ViPipe, 0x3e02, 0xa0); + sc1346_1L_slave_write_register(ViPipe, 0x440e, 0x02); + sc1346_1L_slave_write_register(ViPipe, 0x4509, 0x20); + sc1346_1L_slave_write_register(ViPipe, 0x450d, 0x28); + sc1346_1L_slave_write_register(ViPipe, 0x5780, 0x66); + sc1346_1L_slave_write_register(ViPipe, 0x578d, 0x40); + sc1346_1L_slave_write_register(ViPipe, 0x36e9, 0x20); + sc1346_1L_slave_write_register(ViPipe, 0x37f9, 0x20); + sc1346_1L_slave_write_register(ViPipe, 0x0100, 0x01); + + sc1346_1L_slave_default_reg_init(ViPipe); + + sc1346_1L_slave_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC1346_1L_SLAVE 720P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +/* 720P60 */ +static void sc1346_1L_slave_linear_720p60_init(VI_PIPE ViPipe) +{ + sc1346_1L_slave_write_register(ViPipe, 0x0103, 0x01); + sc1346_1L_slave_write_register(ViPipe, 0x0100, 0x00); + sc1346_1L_slave_write_register(ViPipe, 0x36e9, 0x80); + sc1346_1L_slave_write_register(ViPipe, 0x37f9, 0x80); + sc1346_1L_slave_write_register(ViPipe, 0x301f, 0x02); + sc1346_1L_slave_write_register(ViPipe, 0x3106, 0x05); + sc1346_1L_slave_write_register(ViPipe, 0x3301, 0x0b); + sc1346_1L_slave_write_register(ViPipe, 0x3303, 0x10); + sc1346_1L_slave_write_register(ViPipe, 0x3306, 0x50); + sc1346_1L_slave_write_register(ViPipe, 0x3308, 0x0a); + sc1346_1L_slave_write_register(ViPipe, 0x330a, 0x00); + sc1346_1L_slave_write_register(ViPipe, 0x330b, 0xda); + sc1346_1L_slave_write_register(ViPipe, 0x330e, 0x0a); + sc1346_1L_slave_write_register(ViPipe, 0x331e, 0x61); + sc1346_1L_slave_write_register(ViPipe, 0x331f, 0xa1); + sc1346_1L_slave_write_register(ViPipe, 0x3320, 0x04); + sc1346_1L_slave_write_register(ViPipe, 0x3327, 0x08); + sc1346_1L_slave_write_register(ViPipe, 0x3329, 0x09); + sc1346_1L_slave_write_register(ViPipe, 0x3364, 0x1f); + sc1346_1L_slave_write_register(ViPipe, 0x3390, 0x09); + sc1346_1L_slave_write_register(ViPipe, 0x3391, 0x0f); + sc1346_1L_slave_write_register(ViPipe, 0x3392, 0x1f); + sc1346_1L_slave_write_register(ViPipe, 0x3393, 0x30); + sc1346_1L_slave_write_register(ViPipe, 0x3394, 0xff); + sc1346_1L_slave_write_register(ViPipe, 0x3395, 0xff); + sc1346_1L_slave_write_register(ViPipe, 0x33ad, 0x10); + sc1346_1L_slave_write_register(ViPipe, 0x33b3, 0x40); + sc1346_1L_slave_write_register(ViPipe, 0x33f9, 0x50); + sc1346_1L_slave_write_register(ViPipe, 0x33fb, 0x80); + sc1346_1L_slave_write_register(ViPipe, 0x33fc, 0x09); + sc1346_1L_slave_write_register(ViPipe, 0x33fd, 0x0f); + sc1346_1L_slave_write_register(ViPipe, 0x349f, 0x03); + sc1346_1L_slave_write_register(ViPipe, 0x34a6, 0x09); + sc1346_1L_slave_write_register(ViPipe, 0x34a7, 0x0f); + sc1346_1L_slave_write_register(ViPipe, 0x34a8, 0x40); + sc1346_1L_slave_write_register(ViPipe, 0x34a9, 0x30); + sc1346_1L_slave_write_register(ViPipe, 0x34aa, 0x00); + sc1346_1L_slave_write_register(ViPipe, 0x34ab, 0xe8); + sc1346_1L_slave_write_register(ViPipe, 0x34ac, 0x01); + sc1346_1L_slave_write_register(ViPipe, 0x34ad, 0x0c); + sc1346_1L_slave_write_register(ViPipe, 0x3630, 0xe2); + sc1346_1L_slave_write_register(ViPipe, 0x3632, 0x76); + sc1346_1L_slave_write_register(ViPipe, 0x3633, 0x33); + sc1346_1L_slave_write_register(ViPipe, 0x3639, 0xf4); + sc1346_1L_slave_write_register(ViPipe, 0x3641, 0x28); + sc1346_1L_slave_write_register(ViPipe, 0x3670, 0x09); + sc1346_1L_slave_write_register(ViPipe, 0x3674, 0xe2); + sc1346_1L_slave_write_register(ViPipe, 0x3675, 0xea); + sc1346_1L_slave_write_register(ViPipe, 0x3676, 0xea); + sc1346_1L_slave_write_register(ViPipe, 0x367c, 0x09); + sc1346_1L_slave_write_register(ViPipe, 0x367d, 0x0f); + sc1346_1L_slave_write_register(ViPipe, 0x3690, 0x22); + sc1346_1L_slave_write_register(ViPipe, 0x3691, 0x22); + sc1346_1L_slave_write_register(ViPipe, 0x3692, 0x32); + sc1346_1L_slave_write_register(ViPipe, 0x3698, 0x88); + sc1346_1L_slave_write_register(ViPipe, 0x3699, 0x8f); + sc1346_1L_slave_write_register(ViPipe, 0x369a, 0xa0); + sc1346_1L_slave_write_register(ViPipe, 0x369b, 0xd1); + sc1346_1L_slave_write_register(ViPipe, 0x369c, 0x09); + sc1346_1L_slave_write_register(ViPipe, 0x369d, 0x0f); + sc1346_1L_slave_write_register(ViPipe, 0x36a2, 0x09); + sc1346_1L_slave_write_register(ViPipe, 0x36a3, 0x0b); + sc1346_1L_slave_write_register(ViPipe, 0x36a4, 0x0f); + sc1346_1L_slave_write_register(ViPipe, 0x36d0, 0x01); + sc1346_1L_slave_write_register(ViPipe, 0x36eb, 0x05); + sc1346_1L_slave_write_register(ViPipe, 0x36ec, 0x05); + sc1346_1L_slave_write_register(ViPipe, 0x370f, 0x01); + sc1346_1L_slave_write_register(ViPipe, 0x3722, 0x41); + sc1346_1L_slave_write_register(ViPipe, 0x3724, 0x41); + sc1346_1L_slave_write_register(ViPipe, 0x3725, 0xc1); + sc1346_1L_slave_write_register(ViPipe, 0x3727, 0x14); + sc1346_1L_slave_write_register(ViPipe, 0x3728, 0x00); + sc1346_1L_slave_write_register(ViPipe, 0x37b0, 0x21); + sc1346_1L_slave_write_register(ViPipe, 0x37b1, 0x21); + sc1346_1L_slave_write_register(ViPipe, 0x37b2, 0x37); + sc1346_1L_slave_write_register(ViPipe, 0x37b3, 0x09); + sc1346_1L_slave_write_register(ViPipe, 0x37b4, 0x0f); + sc1346_1L_slave_write_register(ViPipe, 0x37fb, 0x31); + sc1346_1L_slave_write_register(ViPipe, 0x37fc, 0x01); + sc1346_1L_slave_write_register(ViPipe, 0x3903, 0x40); + sc1346_1L_slave_write_register(ViPipe, 0x3904, 0x04); + sc1346_1L_slave_write_register(ViPipe, 0x3905, 0x8d); + sc1346_1L_slave_write_register(ViPipe, 0x3907, 0x00); + sc1346_1L_slave_write_register(ViPipe, 0x3908, 0x41); + sc1346_1L_slave_write_register(ViPipe, 0x391f, 0x41); + sc1346_1L_slave_write_register(ViPipe, 0x3933, 0x80); + sc1346_1L_slave_write_register(ViPipe, 0x3934, 0x0a); + sc1346_1L_slave_write_register(ViPipe, 0x3935, 0x01); + sc1346_1L_slave_write_register(ViPipe, 0x3936, 0x55); + sc1346_1L_slave_write_register(ViPipe, 0x3937, 0x71); + sc1346_1L_slave_write_register(ViPipe, 0x3938, 0x72); + sc1346_1L_slave_write_register(ViPipe, 0x3939, 0x0f); + sc1346_1L_slave_write_register(ViPipe, 0x393a, 0xef); + sc1346_1L_slave_write_register(ViPipe, 0x393b, 0x0f); + sc1346_1L_slave_write_register(ViPipe, 0x393c, 0xcd); + sc1346_1L_slave_write_register(ViPipe, 0x3e01, 0x2e); + sc1346_1L_slave_write_register(ViPipe, 0x3e02, 0x80); + sc1346_1L_slave_write_register(ViPipe, 0x440e, 0x02); + sc1346_1L_slave_write_register(ViPipe, 0x4509, 0x25); + sc1346_1L_slave_write_register(ViPipe, 0x450d, 0x28); + sc1346_1L_slave_write_register(ViPipe, 0x4819, 0x09); + sc1346_1L_slave_write_register(ViPipe, 0x481b, 0x05); + sc1346_1L_slave_write_register(ViPipe, 0x481d, 0x14); + sc1346_1L_slave_write_register(ViPipe, 0x481f, 0x04); + sc1346_1L_slave_write_register(ViPipe, 0x4821, 0x0a); + sc1346_1L_slave_write_register(ViPipe, 0x4823, 0x05); + sc1346_1L_slave_write_register(ViPipe, 0x4825, 0x04); + sc1346_1L_slave_write_register(ViPipe, 0x4827, 0x05); + sc1346_1L_slave_write_register(ViPipe, 0x4829, 0x08); + sc1346_1L_slave_write_register(ViPipe, 0x5780, 0x66); + sc1346_1L_slave_write_register(ViPipe, 0x578d, 0x40); + sc1346_1L_slave_write_register(ViPipe, 0x36e9, 0x20); + sc1346_1L_slave_write_register(ViPipe, 0x37f9, 0x20); + sc1346_1L_slave_write_register(ViPipe, 0x0100, 0x01); + + sc1346_1L_slave_default_reg_init(ViPipe); + + sc1346_1L_slave_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC1346_1L_SLAVE 720P 60fps 10bit LINE Init OK!===\n", ViPipe); + +} \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc200ai/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc200ai/Makefile new file mode 100644 index 00000000..f98c8fb8 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc200ai/sc200ai_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc200ai/sc200ai_cmos.c new file mode 100644 index 00000000..f91e4ca2 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc200ai/sc200ai_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc200ai/sc200ai_cmos_ex.h new file mode 100644 index 00000000..07ce2322 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc200ai/sc200ai_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc200ai/sc200ai_cmos_param.h new file mode 100644 index 00000000..1a02c07e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc200ai/sc200ai_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc200ai/sc200ai_sensor_ctl.c new file mode 100644 index 00000000..d38ca739 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc223a_1L/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc223a_1L/Makefile new file mode 100644 index 00000000..9f548822 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc223a_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_sc223a_1L.a +TARGET_SO = $(MW_LIB)/libsns_sc223a_1L.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc223a_1L/sc223a_1L_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc223a_1L/sc223a_1L_cmos.c new file mode 100644 index 00000000..6da8160b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc223a_1L/sc223a_1L_cmos.c @@ -0,0 +1,918 @@ +#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 "sc223a_1L_cmos_ex.h" +#include "sc223a_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 SC223A_1L_ID 0xCB3E +#define SC223A_1L_I2C_ADDR_1 0x30 +#define SC223A_1L_I2C_ADDR_2 0x32 +#define SENSOR_SC223A_1L_WIDTH 1920 +#define SENSOR_SC223A_1L_HEIGHT 1080 +#define SC223A_1L_I2C_ADDR_IS_VALID(addr) ((addr) == SC223A_1L_I2C_ADDR_1 || (addr) == SC223A_1L_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC223A_1L[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC223A_1L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC223A_1L[dev]) +#define SC223A_1L_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC223A_1L[dev] = pstCtx) +#define SC223A_1L_SENSOR_RESET_CTX(dev) (g_pastSC223A_1L[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC223A_1L_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC223A_1L_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC223A_1L_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +SC223A_1L_STATE_S g_astSC223A_1L_State[VI_MAX_PIPE_NUM] = {{0} }; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc223a_1l_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); +/*****SC223A_1L Lines Range*****/ +#define SC223A_1L_FULL_LINES_MAX (0xFFFF) + +/*****SC223A_1L Register Address*****/ +#define SC223A_1L_SHS1_0_ADDR 0x3E00 +#define SC223A_1L_SHS1_1_ADDR 0x3E01 +#define SC223A_1L_SHS1_2_ADDR 0x3E02 +#define SC223A_1L_AGAIN0_ADDR 0x3E09 +#define SC223A_1L_DGAIN0_ADDR 0x3E06 +#define SC223A_1L_VMAX_ADDR 0x320E +#define SC223A_1L_TABLE_END 0xFFFF + +#define SC223A_1L_RES_IS_1080P(w, h) ((w) <= SENSOR_SC223A_1L_WIDTH && (h) <= SENSOR_SC223A_1L_HEIGHT) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC223A_1L_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC223A_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC223A_1L_mode[pstSnsState->u8ImgMode]; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC223A_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_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] : pstMode->stExp[0].u16Def; + + 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); + SC223A_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC223A_1L_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC223A_1L_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC223A_1L_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC223A_1L_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 > SC223A_1L_FULL_LINES_MAX) ? SC223A_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_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; + CVI_U32 u32TmpIntTime, u32MinTime, u32MaxTime; + + SC223A_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 : 0 + * max : 2 * vts - 10 + * step : 1 + */ + + u32MinTime = 2; + u32MaxTime = 2 * pstSnsState->au32FL[0] - 13; + u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0]; + u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : 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 CVI_U32 Again_table[] = { + 1024, 1853, 3707, 7414, 14828, 29655, 59310 +}; + +static CVI_U32 AgainReg[] = { + 0x00, 0x40, 0x41, 0x43, 0x47, 0x4f, 0x5f +}; + +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; + + SC223A_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 */ + + /* 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 SC223A_1L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC223A_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC223A_1L_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; + + SC223A_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC223A_1L_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC223A_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); + SC223A_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_aunSC223A_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 = sc223a_1l_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc223a_1l_addr_byte; + pstI2c_data[i].u32DataByteNum = sc223a_1l_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 = SC223A_1L_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC223A_1L_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC223A_1L_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC223A_1L_AGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC223A_1L_DGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC223A_1L_DGAIN0_ADDR + 1; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC223A_1L_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC223A_1L_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); + SC223A_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 (SC223A_1L_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC223A_1L_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_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC223A_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeSc223a_1l_MirrorFip[ViPipe] != eSnsMirrorFlip) { + sc223a_1l_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeSc223a_1l_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC223A_1L_MODE_S *pstMode = CVI_NULL; + + SC223A_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC223A_1L_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC223A_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; + + SC223A_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc223a_1l_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC223A_1L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC223A_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 = &sc223a_1l_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 = sc223a_1l_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc223a_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 (SC223A_1L_I2C_ADDR_IS_VALID(s32I2cAddr)) + sc223a_1l_i2c_addr = s32I2cAddr; +} + +static CVI_S32 sc223a_1l_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC223A_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; + + SC223A_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)); + + SC223A_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; + + SC223A_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC223A_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 = SC223A_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, SC223A_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, SC223A_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, SC223A_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_au16SC223A_1L_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC223A_1L_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC223A_1L_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc223a_1l_standby, + .pfnRestart = sc223a_1l_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = sc223a_1l_write_register, + .pfnReadReg = sc223a_1l_read_register, + .pfnSetBusInfo = sc223a_1l_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 = sc223a_1l_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc223a_1L/sc223a_1L_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc223a_1L/sc223a_1L_cmos_ex.h new file mode 100644 index 00000000..a96cf701 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc223a_1L/sc223a_1L_cmos_ex.h @@ -0,0 +1,85 @@ +#ifndef __SC223A_1L_CMOS_EX_H_ +#define __SC223A_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 sc223a_1l_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 _SC223A_1L_MODE_E { + SC223A_1L_MODE_1080P30 = 0, + SC223A_1L_MODE_LINEAR_NUM, + SC223A_1L_MODE_NUM +} SC223A_1L_MODE_E; + +typedef struct _SC223A_1L_STATE_S { + CVI_U32 u32Sexp_MAX; +} SC223A_1L_STATE_S; + +typedef struct _SC223A_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_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16SexpMaxReg; + char name[64]; +} SC223A_1L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC223A_1L[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC223A_1L_BusInfo[]; +extern CVI_U16 g_au16SC223A_1L_GainMode[]; +extern CVI_U16 g_au16SC223A_1L_L2SMode[]; +extern CVI_U8 sc223a_1l_i2c_addr; +extern const CVI_U32 sc223a_1l_addr_byte; +extern const CVI_U32 sc223a_1l_data_byte; +extern void sc223a_1l_init(VI_PIPE ViPipe); +extern void sc223a_1l_exit(VI_PIPE ViPipe); +extern void sc223a_1l_standby(VI_PIPE ViPipe); +extern void sc223a_1l_restart(VI_PIPE ViPipe); +extern int sc223a_1l_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc223a_1l_read_register(VI_PIPE ViPipe, int addr); +extern void sc223a_1l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc223a_1l_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC223A_1L_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc223a_1L/sc223a_1L_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc223a_1L/sc223a_1L_cmos_param.h new file mode 100644 index 00000000..d5733f43 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc223a_1L/sc223a_1L_cmos_param.h @@ -0,0 +1,125 @@ +#ifndef __SC223A_1L_CMOS_PARAM_H_ +#define __SC223A_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 "sc223a_1L_cmos_ex.h" + +static const SC223A_1L_MODE_S g_astSC223A_1L_mode[SC223A_1L_MODE_NUM] = { + [SC223A_1L_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 = 2200, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1125 - 4, //(1125*2 - 8)/2 + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 58 * 1024, + .u16Def = 1024, + .u16Step = 1, + }, + .stDgain[0] = { + .u16Min = 1024, + .u16Max = 4 * 1024, + .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 sc223a_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, + .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 /* __SC223A_1L_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc223a_1L/sc223a_1L_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc223a_1L/sc223a_1L_sensor_ctl.c new file mode 100644 index 00000000..fd42142d --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc223a_1L/sc223a_1L_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 "sc223a_1L_cmos_ex.h" + +#define SC223A_1L_CHIP_ID_HI_ADDR 0x3107 +#define SC223A_1L_CHIP_ID_LO_ADDR 0x3108 +#define SC223A_1L_CHIP_ID 0xcb3e + +static void sc223a_1l_linear_1080p30_init(VI_PIPE ViPipe); + +CVI_U8 sc223a_1l_i2c_addr = 0x30; /* I2C Address of SC223A_1L */ +const CVI_U32 sc223a_1l_addr_byte = 2; +const CVI_U32 sc223a_1l_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc223a_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_aunSC223A_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, sc223a_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 sc223a_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 sc223a_1l_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 (sc223a_1l_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc223a_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, sc223a_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 (sc223a_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 sc223a_1l_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 (sc223a_1l_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc223a_1l_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc223a_1l_addr_byte + sc223a_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 sc223a_1l_standby(VI_PIPE ViPipe) +{ + sc223a_1l_write_register(ViPipe, 0x0100, 0x00); /* suspend */ +} + +void sc223a_1l_restart(VI_PIPE ViPipe) +{ + sc223a_1l_write_register(ViPipe, 0x0100, 0x01); /* resume */ +} + +void sc223a_1l_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC223A_1L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc223a_1l_write_register(ViPipe, + g_pastSC223A_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC223A_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void sc223a_1l_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; + } + + sc223a_1l_write_register(ViPipe, 0x3221, val); +} + +int sc223a_1l_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc223a_1l_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc223a_1l_read_register(ViPipe, SC223A_1L_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 = sc223a_1l_read_register(ViPipe, SC223A_1L_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 != SC223A_1L_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc223a_1l_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + + enWDRMode = g_pastSC223A_1L[ViPipe]->enWDRMode; + + sc223a_1l_i2c_init(ViPipe); + + if (enWDRMode == WDR_MODE_NONE) { + sc223a_1l_linear_1080p30_init(ViPipe); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n"); + } + + g_pastSC223A_1L[ViPipe]->bInit = CVI_TRUE; +} + +void sc223a_1l_exit(VI_PIPE ViPipe) +{ + sc223a_1l_i2c_exit(ViPipe); +} + +static void sc223a_1l_linear_1080p30_init(VI_PIPE ViPipe) +{ + sc223a_1l_write_register(ViPipe, 0x0100, 0x00); + sc223a_1l_write_register(ViPipe, 0x36e9, 0x80); + sc223a_1l_write_register(ViPipe, 0x37f9, 0x80); + sc223a_1l_write_register(ViPipe, 0x3018, 0x1a); + sc223a_1l_write_register(ViPipe, 0x3019, 0x02); + sc223a_1l_write_register(ViPipe, 0x301f, 0x02); + sc223a_1l_write_register(ViPipe, 0x30b8, 0x44); + sc223a_1l_write_register(ViPipe, 0x3253, 0x0c); + sc223a_1l_write_register(ViPipe, 0x3281, 0x80); + sc223a_1l_write_register(ViPipe, 0x3301, 0x06); + sc223a_1l_write_register(ViPipe, 0x3302, 0x12); + sc223a_1l_write_register(ViPipe, 0x3306, 0x80); + sc223a_1l_write_register(ViPipe, 0x3309, 0x60); + sc223a_1l_write_register(ViPipe, 0x330a, 0x00); + sc223a_1l_write_register(ViPipe, 0x330b, 0xe0); + sc223a_1l_write_register(ViPipe, 0x330d, 0x20); + sc223a_1l_write_register(ViPipe, 0x3314, 0x15); + sc223a_1l_write_register(ViPipe, 0x331e, 0x41); + sc223a_1l_write_register(ViPipe, 0x331f, 0x51); + sc223a_1l_write_register(ViPipe, 0x3320, 0x0a); + sc223a_1l_write_register(ViPipe, 0x3326, 0x0e); + sc223a_1l_write_register(ViPipe, 0x3333, 0x10); + sc223a_1l_write_register(ViPipe, 0x3334, 0x40); + sc223a_1l_write_register(ViPipe, 0x335d, 0x60); + sc223a_1l_write_register(ViPipe, 0x335e, 0x06); + sc223a_1l_write_register(ViPipe, 0x335f, 0x08); + sc223a_1l_write_register(ViPipe, 0x3364, 0x56); + sc223a_1l_write_register(ViPipe, 0x337a, 0x06); + sc223a_1l_write_register(ViPipe, 0x337b, 0x0e); + sc223a_1l_write_register(ViPipe, 0x337c, 0x02); + sc223a_1l_write_register(ViPipe, 0x337d, 0x0a); + sc223a_1l_write_register(ViPipe, 0x3390, 0x03); + sc223a_1l_write_register(ViPipe, 0x3391, 0x0f); + sc223a_1l_write_register(ViPipe, 0x3392, 0x1f); + sc223a_1l_write_register(ViPipe, 0x3393, 0x06); + sc223a_1l_write_register(ViPipe, 0x3394, 0x06); + sc223a_1l_write_register(ViPipe, 0x3395, 0x06); + sc223a_1l_write_register(ViPipe, 0x3396, 0x48); + sc223a_1l_write_register(ViPipe, 0x3397, 0x4b); + sc223a_1l_write_register(ViPipe, 0x3398, 0x5f); + sc223a_1l_write_register(ViPipe, 0x3399, 0x06); + sc223a_1l_write_register(ViPipe, 0x339a, 0x06); + sc223a_1l_write_register(ViPipe, 0x339b, 0x92); + sc223a_1l_write_register(ViPipe, 0x339c, 0x92); + sc223a_1l_write_register(ViPipe, 0x33a2, 0x04); + sc223a_1l_write_register(ViPipe, 0x33a3, 0x0a); + sc223a_1l_write_register(ViPipe, 0x33ad, 0x1c); + sc223a_1l_write_register(ViPipe, 0x33af, 0x40); + sc223a_1l_write_register(ViPipe, 0x33b1, 0x80); + sc223a_1l_write_register(ViPipe, 0x33b3, 0x20); + sc223a_1l_write_register(ViPipe, 0x349f, 0x02); + sc223a_1l_write_register(ViPipe, 0x34a6, 0x48); + sc223a_1l_write_register(ViPipe, 0x34a7, 0x4b); + sc223a_1l_write_register(ViPipe, 0x34a8, 0x20); + sc223a_1l_write_register(ViPipe, 0x34a9, 0x20); + sc223a_1l_write_register(ViPipe, 0x34f8, 0x5f); + sc223a_1l_write_register(ViPipe, 0x34f9, 0x10); + sc223a_1l_write_register(ViPipe, 0x3616, 0xac); + sc223a_1l_write_register(ViPipe, 0x3630, 0xc0); + sc223a_1l_write_register(ViPipe, 0x3631, 0x86); + sc223a_1l_write_register(ViPipe, 0x3632, 0x26); + sc223a_1l_write_register(ViPipe, 0x3633, 0x32); + sc223a_1l_write_register(ViPipe, 0x3637, 0x29); + sc223a_1l_write_register(ViPipe, 0x363a, 0x84); + sc223a_1l_write_register(ViPipe, 0x363b, 0x04); + sc223a_1l_write_register(ViPipe, 0x363c, 0x08); + sc223a_1l_write_register(ViPipe, 0x3641, 0x3a); + sc223a_1l_write_register(ViPipe, 0x364f, 0x39); + sc223a_1l_write_register(ViPipe, 0x3670, 0xce); + sc223a_1l_write_register(ViPipe, 0x3674, 0xc0); + sc223a_1l_write_register(ViPipe, 0x3675, 0xc0); + sc223a_1l_write_register(ViPipe, 0x3676, 0xc0); + sc223a_1l_write_register(ViPipe, 0x3677, 0x86); + sc223a_1l_write_register(ViPipe, 0x3678, 0x8b); + sc223a_1l_write_register(ViPipe, 0x3679, 0x8c); + sc223a_1l_write_register(ViPipe, 0x367c, 0x4b); + sc223a_1l_write_register(ViPipe, 0x367d, 0x5f); + sc223a_1l_write_register(ViPipe, 0x367e, 0x4b); + sc223a_1l_write_register(ViPipe, 0x367f, 0x5f); + sc223a_1l_write_register(ViPipe, 0x3690, 0x62); + sc223a_1l_write_register(ViPipe, 0x3691, 0x63); + sc223a_1l_write_register(ViPipe, 0x3692, 0x63); + sc223a_1l_write_register(ViPipe, 0x3699, 0x86); + sc223a_1l_write_register(ViPipe, 0x369a, 0x92); + sc223a_1l_write_register(ViPipe, 0x369b, 0xa4); + sc223a_1l_write_register(ViPipe, 0x369c, 0x48); + sc223a_1l_write_register(ViPipe, 0x369d, 0x4b); + sc223a_1l_write_register(ViPipe, 0x36a2, 0x4b); + sc223a_1l_write_register(ViPipe, 0x36a3, 0x4f); + sc223a_1l_write_register(ViPipe, 0x36ec, 0x0c); + sc223a_1l_write_register(ViPipe, 0x370f, 0x01); + sc223a_1l_write_register(ViPipe, 0x3721, 0x6c); + sc223a_1l_write_register(ViPipe, 0x3722, 0x09); + sc223a_1l_write_register(ViPipe, 0x3724, 0x41); + sc223a_1l_write_register(ViPipe, 0x3725, 0xc4); + sc223a_1l_write_register(ViPipe, 0x37b0, 0x09); + sc223a_1l_write_register(ViPipe, 0x37b1, 0x09); + sc223a_1l_write_register(ViPipe, 0x37b2, 0x09); + sc223a_1l_write_register(ViPipe, 0x37b3, 0x48); + sc223a_1l_write_register(ViPipe, 0x37b4, 0x5f); + sc223a_1l_write_register(ViPipe, 0x3900, 0x19); + sc223a_1l_write_register(ViPipe, 0x3901, 0x02); + sc223a_1l_write_register(ViPipe, 0x3905, 0xb8); + sc223a_1l_write_register(ViPipe, 0x391b, 0x82); + sc223a_1l_write_register(ViPipe, 0x391c, 0x00); + sc223a_1l_write_register(ViPipe, 0x391f, 0x04); + sc223a_1l_write_register(ViPipe, 0x3933, 0x81); + sc223a_1l_write_register(ViPipe, 0x3934, 0x4c); + sc223a_1l_write_register(ViPipe, 0x393f, 0xff); + sc223a_1l_write_register(ViPipe, 0x3940, 0x73); + sc223a_1l_write_register(ViPipe, 0x3942, 0x01); + sc223a_1l_write_register(ViPipe, 0x3943, 0x4d); + sc223a_1l_write_register(ViPipe, 0x3946, 0x20); + sc223a_1l_write_register(ViPipe, 0x3957, 0x86); + sc223a_1l_write_register(ViPipe, 0x3e01, 0x8c); + sc223a_1l_write_register(ViPipe, 0x3e28, 0xc4); + sc223a_1l_write_register(ViPipe, 0x440e, 0x02); + sc223a_1l_write_register(ViPipe, 0x4501, 0xc0); + sc223a_1l_write_register(ViPipe, 0x4509, 0x14); + sc223a_1l_write_register(ViPipe, 0x450d, 0x11); + sc223a_1l_write_register(ViPipe, 0x4518, 0x00); + sc223a_1l_write_register(ViPipe, 0x451b, 0x0a); + sc223a_1l_write_register(ViPipe, 0x4819, 0x09); + sc223a_1l_write_register(ViPipe, 0x481b, 0x05); + sc223a_1l_write_register(ViPipe, 0x481d, 0x14); + sc223a_1l_write_register(ViPipe, 0x481f, 0x04); + sc223a_1l_write_register(ViPipe, 0x4821, 0x0a); + sc223a_1l_write_register(ViPipe, 0x4823, 0x05); + sc223a_1l_write_register(ViPipe, 0x4825, 0x04); + sc223a_1l_write_register(ViPipe, 0x4827, 0x05); + sc223a_1l_write_register(ViPipe, 0x4829, 0x08); + sc223a_1l_write_register(ViPipe, 0x501c, 0x00); + sc223a_1l_write_register(ViPipe, 0x501d, 0x60); + sc223a_1l_write_register(ViPipe, 0x501e, 0x00); + sc223a_1l_write_register(ViPipe, 0x501f, 0x40); + sc223a_1l_write_register(ViPipe, 0x5799, 0x06); + sc223a_1l_write_register(ViPipe, 0x5ae0, 0xfe); + sc223a_1l_write_register(ViPipe, 0x5ae1, 0x40); + sc223a_1l_write_register(ViPipe, 0x5ae2, 0x38); + sc223a_1l_write_register(ViPipe, 0x5ae3, 0x30); + sc223a_1l_write_register(ViPipe, 0x5ae4, 0x28); + sc223a_1l_write_register(ViPipe, 0x5ae5, 0x38); + sc223a_1l_write_register(ViPipe, 0x5ae6, 0x30); + sc223a_1l_write_register(ViPipe, 0x5ae7, 0x28); + sc223a_1l_write_register(ViPipe, 0x5ae8, 0x3f); + sc223a_1l_write_register(ViPipe, 0x5ae9, 0x34); + sc223a_1l_write_register(ViPipe, 0x5aea, 0x2c); + sc223a_1l_write_register(ViPipe, 0x5aeb, 0x3f); + sc223a_1l_write_register(ViPipe, 0x5aec, 0x34); + sc223a_1l_write_register(ViPipe, 0x5aed, 0x2c); + sc223a_1l_write_register(ViPipe, 0x5aee, 0xfe); + sc223a_1l_write_register(ViPipe, 0x5aef, 0x40); + sc223a_1l_write_register(ViPipe, 0x5af4, 0x38); + sc223a_1l_write_register(ViPipe, 0x5af5, 0x30); + sc223a_1l_write_register(ViPipe, 0x5af6, 0x28); + sc223a_1l_write_register(ViPipe, 0x5af7, 0x38); + sc223a_1l_write_register(ViPipe, 0x5af8, 0x30); + sc223a_1l_write_register(ViPipe, 0x5af9, 0x28); + sc223a_1l_write_register(ViPipe, 0x5afa, 0x3f); + sc223a_1l_write_register(ViPipe, 0x5afb, 0x34); + sc223a_1l_write_register(ViPipe, 0x5afc, 0x2c); + sc223a_1l_write_register(ViPipe, 0x5afd, 0x3f); + sc223a_1l_write_register(ViPipe, 0x5afe, 0x34); + sc223a_1l_write_register(ViPipe, 0x5aff, 0x2c); + sc223a_1l_write_register(ViPipe, 0x36e9, 0x20); + sc223a_1l_write_register(ViPipe, 0x37f9, 0x27); + // sc223a_1l_write_register(ViPipe, 0x0100, 0x01); + + sc223a_1l_default_reg_init(ViPipe); + + sc223a_1l_write_register(ViPipe, 0x0100, 0x01); + delay_ms(50); + printf("ViPipe:%d,===SC223A_1L 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L/Makefile new file mode 100644 index 00000000..a91b7c4b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_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_sc2331_1L.a +TARGET_SO = $(MW_LIB)/libsns_sc2331_1L.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L/sc2331_1L_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L/sc2331_1L_cmos.c new file mode 100644 index 00000000..a15f1b24 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L/sc2331_1L_cmos.c @@ -0,0 +1,990 @@ +#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 "sc2331_1L_cmos_ex.h" +#include "sc2331_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 SC2331_1L_ID 0xCB5C +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC2331_1L[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC2331_1L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC2331_1L[dev]) +#define SC2331_1L_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC2331_1L[dev] = pstCtx) +#define SC2331_1L_SENSOR_RESET_CTX(dev) (g_pastSC2331_1L[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC2331_1L_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC2331_1L_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC2331_1L_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc2331_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); +/*****SC2331_1L Lines Range*****/ +#define SC2331_1L_FULL_LINES_MAX (0x7FFF) + +/*****SC2331_1L Register Address*****/ +#define SC2331_1L_EXP_H_ADDR (0x3e00) +#define SC2331_1L_EXP_M_ADDR (0x3e01) +#define SC2331_1L_EXP_L_ADDR (0x3e02) + +#define SC2331_1L_AGAIN_H_ADDR (0x3e08) + +#define SC2331_1L_DGAIN_H_ADDR (0x3e06) +#define SC2331_1L_DGAIN_L_ADDR (0x3e07) + +#define SC2331_1L_VMAX_H_ADDR (0x320e) +#define SC2331_1L_VMAX_L_ADDR (0x320f) + +#define SC2331_1L_GAIN_DPC_ADDR (0x5799) +#define SC2331_1L_HOLD_ADDR (0x3812) + +#define SC2331_1L_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +#define SC2331_1L_EXPACCURACY (0.5) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC2331_1L_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC2331_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC2331_1L_mode[pstSnsState->u8ImgMode]; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC2331_1L_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = SC2331_1L_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); + SC2331_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC2331_1L_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC2331_1L_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC2331_1L_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC2331_1L_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 > SC2331_1L_FULL_LINES_MAX) ? SC2331_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 = 2 * pstSnsState->u32FLStd - 13; + 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; + + SC2331_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 : 3 + * max : 2 * vts - 10 + * step : 1 + */ + u32MinTime = 2; + u32MaxTime = 2 * pstSnsState->au32FL[0] - 13; + 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[6] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 4064, + .idxBase = 64, + .regGain = 0x08, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 8128, + .idxBase = 128, + .regGain = 0x09, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 16256, + .idxBase = 192, + .regGain = 0x0b, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 32512, + .idxBase = 256, + .regGain = 0x0f, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 32768, + .idxBase = 320, + .regGain = 0x1f, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, +}; +static CVI_U32 Again_table[321] = { + 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, 32768 +}; + +static struct gain_tbl_info_s DgainInfo[3] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 4064, + .idxBase = 64, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 4096, + .idxBase = 128, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, +}; + +static CVI_U32 Dgain_table[129] = { + 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 +}; + +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[320]) { + *pu32AgainLin = Again_table[320]; + *pu32AgainDb = 320; + return CVI_SUCCESS; + } + + for (i = 1; i < 321; 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[128]) { + *pu32DgainLin = Dgain_table[128]; + *pu32DgainDb = 128; + return CVI_SUCCESS; + } + + for (i = 1; i < 129; 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; + + SC2331_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 & 0xFF); + u32Again = info->regGainFineBase + (u32Again - info->idxBase) * info->regGainFineStep; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L_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 SC2331_1L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2331_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC2331_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; + + SC2331_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC2331_1L_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC2331_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); + SC2331_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_aunSC2331_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 = sc2331_1L_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc2331_1L_addr_byte; + pstI2c_data[i].u32DataByteNum = sc2331_1L_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC2331_1L_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_M_ADDR].u32RegAddr = SC2331_1L_EXP_M_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC2331_1L_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H_ADDR].u32RegAddr = SC2331_1L_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L_ADDR].u32RegAddr = SC2331_1L_DGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC2331_1L_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC2331_1L_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC2331_1L_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC2331_1L_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); + SC2331_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 (SC2331_1L_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC2331_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; + } + } + + 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; + + SC2331_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeSc2331_MirrorFip[ViPipe] != eSnsMirrorFlip) { + sc2331_1L_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeSc2331_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC2331_1L_MODE_S *pstMode = CVI_NULL; + + SC2331_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC2331_1L_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC2331_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; + + SC2331_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc2331_1L_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC2331_1L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC2331_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 = &sc2331_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 = sc2331_1L_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc2331_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 sc2331_1L_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC2331_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; + + SC2331_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)); + + SC2331_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; + + SC2331_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC2331_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 = SC2331_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, SC2331_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, SC2331_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, SC2331_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_au16SC2331_1L_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC2331_1L_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC2331_1L_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc2331_1L_standby, + .pfnRestart = sc2331_1L_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = sc2331_1L_write_register, + .pfnReadReg = sc2331_1L_read_register, + .pfnSetBusInfo = sc2331_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 = sc2331_1L_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L/sc2331_1L_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L/sc2331_1L_cmos_ex.h new file mode 100644 index 00000000..9678e34a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L/sc2331_1L_cmos_ex.h @@ -0,0 +1,80 @@ +#ifndef __SC2331_1L_CMOS_EX_H_ +#define __SC2331_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 sc2331_1L_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_REGS_NUM +}; + +typedef enum _SC2331_1L_MODE_E { + SC2331_1L_MODE_1920X1080P30 = 0, + SC2331_1L_MODE_LINEAR_NUM, + SC2331_1L_MODE_NUM +} SC2331_1L_MODE_E; + +typedef struct _SC2331_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_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + char name[64]; +} SC2331_1L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC2331_1L[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC2331_1L_BusInfo[]; +extern CVI_U16 g_au16SC2331_1L_GainMode[]; +extern CVI_U16 g_au16SC2331_1L_L2SMode[]; +extern const CVI_U8 sc2331_1L_i2c_addr; +extern const CVI_U32 sc2331_1L_addr_byte; +extern const CVI_U32 sc2331_1L_data_byte; +extern void sc2331_1L_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void sc2331_1L_init(VI_PIPE ViPipe); +extern void sc2331_1L_exit(VI_PIPE ViPipe); +extern void sc2331_1L_standby(VI_PIPE ViPipe); +extern void sc2331_1L_restart(VI_PIPE ViPipe); +extern int sc2331_1L_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc2331_1L_read_register(VI_PIPE ViPipe, int addr); +extern int sc2331_1L_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC2331_1L_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L/sc2331_1L_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L/sc2331_1L_cmos_param.h new file mode 100644 index 00000000..011d32e7 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L/sc2331_1L_cmos_param.h @@ -0,0 +1,125 @@ +#ifndef __SC2331_1L_CMOS_PARAM_H_ +#define __SC2331_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 "sc2331_1L_cmos_ex.h" + +static const SC2331_1L_MODE_S g_astSC2331_1L_mode[SC2331_1L_MODE_NUM] = { + [SC2331_1L_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 / 0xFFFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 2,//3 + .u16Max = 1125 - 13, + .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 = {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 sc2331_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, 2, -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 /* __SC2331_1L_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L/sc2331_1L_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L/sc2331_1L_sensor_ctl.c new file mode 100644 index 00000000..a8e370f1 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L/sc2331_1L_sensor_ctl.c @@ -0,0 +1,389 @@ +#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 "sc2331_1L_cmos_ex.h" + +#define SC2331_1L_CHIP_ID_HI_ADDR 0x3107 +#define SC2331_1L_CHIP_ID_LO_ADDR 0x3108 +#define SC2331_1L_CHIP_ID 0xcb5c + +static void sc2331_1L_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc2331_1L_i2c_addr = 0x30; /* I2C Address of SC2331_1L */ +const CVI_U32 sc2331_1L_addr_byte = 2; +const CVI_U32 sc2331_1L_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc2331_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_aunSC2331_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, sc2331_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 sc2331_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 sc2331_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 (sc2331_1L_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc2331_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, sc2331_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 (sc2331_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 sc2331_1L_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 (sc2331_1L_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc2331_1L_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc2331_1L_addr_byte + sc2331_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 sc2331_1L_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) + sc2331_1L_write_register(ViPipe, addr, data); + } +} + +void sc2331_1L_standby(VI_PIPE ViPipe) +{ + sc2331_1L_write_register(ViPipe, 0x0100, 0x00); +} + +void sc2331_1L_restart(VI_PIPE ViPipe) +{ + sc2331_1L_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc2331_1L_write_register(ViPipe, 0x0100, 0x01); +} + +void sc2331_1L_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC2331_1L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC2331_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc2331_1L_write_register(ViPipe, + g_pastSC2331_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC2331_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc2331_1L_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; + } + + sc2331_1L_write_register(ViPipe, 0x3221, val); +} + + +int sc2331_1L_probe(VI_PIPE ViPipe) +{ +int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc2331_1L_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc2331_1L_read_register(ViPipe, SC2331_1L_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 = sc2331_1L_read_register(ViPipe, SC2331_1L_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 != SC2331_1L_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + +// printf("======%d\n",ViPipe); + return CVI_SUCCESS; +} + + + +/* 1080P30 and 1080P25 */ +static void sc2331_1L_linear_1080p30_init(VI_PIPE ViPipe) +{ + sc2331_1L_write_register(ViPipe, 0x0103, 0x01); + sc2331_1L_write_register(ViPipe, 0x0100, 0x00); + sc2331_1L_write_register(ViPipe, 0x36e9, 0x80); + sc2331_1L_write_register(ViPipe, 0x37f9, 0x80); + sc2331_1L_write_register(ViPipe, 0x3018, 0x1a); + sc2331_1L_write_register(ViPipe, 0x3019, 0x0e); + sc2331_1L_write_register(ViPipe, 0x301f, 0x20); + printf("awei 20 hao 11:07 sc2331_1L\n"); + sc2331_1L_write_register(ViPipe, 0x3258, 0x0e); + sc2331_1L_write_register(ViPipe, 0x3301, 0x06); + sc2331_1L_write_register(ViPipe, 0x3302, 0x10); + sc2331_1L_write_register(ViPipe, 0x3304, 0x68); + sc2331_1L_write_register(ViPipe, 0x3306, 0x90); + sc2331_1L_write_register(ViPipe, 0x3308, 0x18); + sc2331_1L_write_register(ViPipe, 0x3309, 0x80); + sc2331_1L_write_register(ViPipe, 0x330a, 0x01); + sc2331_1L_write_register(ViPipe, 0x330b, 0x48); + sc2331_1L_write_register(ViPipe, 0x330d, 0x18); + sc2331_1L_write_register(ViPipe, 0x331c, 0x02); + sc2331_1L_write_register(ViPipe, 0x331e, 0x59); + sc2331_1L_write_register(ViPipe, 0x331f, 0x71); + sc2331_1L_write_register(ViPipe, 0x3333, 0x10); + sc2331_1L_write_register(ViPipe, 0x3334, 0x40); + sc2331_1L_write_register(ViPipe, 0x3364, 0x56); + sc2331_1L_write_register(ViPipe, 0x3390, 0x08); + sc2331_1L_write_register(ViPipe, 0x3391, 0x09); + sc2331_1L_write_register(ViPipe, 0x3392, 0x0b); + sc2331_1L_write_register(ViPipe, 0x3393, 0x0a); + sc2331_1L_write_register(ViPipe, 0x3394, 0x2a); + sc2331_1L_write_register(ViPipe, 0x3395, 0x2a); + sc2331_1L_write_register(ViPipe, 0x3396, 0x48); + sc2331_1L_write_register(ViPipe, 0x3397, 0x49); + sc2331_1L_write_register(ViPipe, 0x3398, 0x4b); + sc2331_1L_write_register(ViPipe, 0x3399, 0x06); + sc2331_1L_write_register(ViPipe, 0x339a, 0x0a); + sc2331_1L_write_register(ViPipe, 0x339b, 0x30); + sc2331_1L_write_register(ViPipe, 0x339c, 0x48); + sc2331_1L_write_register(ViPipe, 0x33ad, 0x2c); + sc2331_1L_write_register(ViPipe, 0x33ae, 0x38); + sc2331_1L_write_register(ViPipe, 0x33b3, 0x40); + sc2331_1L_write_register(ViPipe, 0x349f, 0x02); + sc2331_1L_write_register(ViPipe, 0x34a6, 0x09); + sc2331_1L_write_register(ViPipe, 0x34a7, 0x0f); + sc2331_1L_write_register(ViPipe, 0x34a8, 0x30); + sc2331_1L_write_register(ViPipe, 0x34a9, 0x28); + sc2331_1L_write_register(ViPipe, 0x34f8, 0x5f); + sc2331_1L_write_register(ViPipe, 0x34f9, 0x28); + sc2331_1L_write_register(ViPipe, 0x3630, 0xc6); + sc2331_1L_write_register(ViPipe, 0x3633, 0x33); + sc2331_1L_write_register(ViPipe, 0x3637, 0x6b); + sc2331_1L_write_register(ViPipe, 0x363c, 0xc1); + sc2331_1L_write_register(ViPipe, 0x363e, 0xc2); + sc2331_1L_write_register(ViPipe, 0x3670, 0x2e); + sc2331_1L_write_register(ViPipe, 0x3674, 0xc5); + sc2331_1L_write_register(ViPipe, 0x3675, 0xc7); + sc2331_1L_write_register(ViPipe, 0x3676, 0xcb); + sc2331_1L_write_register(ViPipe, 0x3677, 0x44); + sc2331_1L_write_register(ViPipe, 0x3678, 0x48); + sc2331_1L_write_register(ViPipe, 0x3679, 0x48); + sc2331_1L_write_register(ViPipe, 0x367c, 0x08); + sc2331_1L_write_register(ViPipe, 0x367d, 0x0b); + sc2331_1L_write_register(ViPipe, 0x367e, 0x0b); + sc2331_1L_write_register(ViPipe, 0x367f, 0x0f); + sc2331_1L_write_register(ViPipe, 0x3690, 0x33); + sc2331_1L_write_register(ViPipe, 0x3691, 0x33); + sc2331_1L_write_register(ViPipe, 0x3692, 0x33); + sc2331_1L_write_register(ViPipe, 0x3693, 0x84); + sc2331_1L_write_register(ViPipe, 0x3694, 0x85); + sc2331_1L_write_register(ViPipe, 0x3695, 0x8d); + sc2331_1L_write_register(ViPipe, 0x3696, 0x9c); + sc2331_1L_write_register(ViPipe, 0x369c, 0x0b); + sc2331_1L_write_register(ViPipe, 0x369d, 0x0f); + sc2331_1L_write_register(ViPipe, 0x369e, 0x09); + sc2331_1L_write_register(ViPipe, 0x369f, 0x0b); + sc2331_1L_write_register(ViPipe, 0x36a0, 0x0f); + sc2331_1L_write_register(ViPipe, 0x36ec, 0x0c); + sc2331_1L_write_register(ViPipe, 0x370f, 0x01); + sc2331_1L_write_register(ViPipe, 0x3722, 0x05); + sc2331_1L_write_register(ViPipe, 0x3724, 0x20); + sc2331_1L_write_register(ViPipe, 0x3725, 0x91); + sc2331_1L_write_register(ViPipe, 0x3771, 0x05); + sc2331_1L_write_register(ViPipe, 0x3772, 0x05); + sc2331_1L_write_register(ViPipe, 0x3773, 0x05); + sc2331_1L_write_register(ViPipe, 0x377a, 0x0b); + sc2331_1L_write_register(ViPipe, 0x377b, 0x0f); + sc2331_1L_write_register(ViPipe, 0x3900, 0x19); + sc2331_1L_write_register(ViPipe, 0x3905, 0xb8); + sc2331_1L_write_register(ViPipe, 0x391b, 0x80); + sc2331_1L_write_register(ViPipe, 0x391c, 0x04); + sc2331_1L_write_register(ViPipe, 0x391d, 0x81); + sc2331_1L_write_register(ViPipe, 0x3933, 0xc0); + sc2331_1L_write_register(ViPipe, 0x3934, 0x08); + sc2331_1L_write_register(ViPipe, 0x3940, 0x72); + sc2331_1L_write_register(ViPipe, 0x3941, 0x00); + sc2331_1L_write_register(ViPipe, 0x3942, 0x00); + sc2331_1L_write_register(ViPipe, 0x3943, 0x09); + sc2331_1L_write_register(ViPipe, 0x3946, 0x10); + sc2331_1L_write_register(ViPipe, 0x3957, 0x86); + sc2331_1L_write_register(ViPipe, 0x3e01, 0x8b); + sc2331_1L_write_register(ViPipe, 0x3e02, 0xd0); + sc2331_1L_write_register(ViPipe, 0x3e08, 0x00); + sc2331_1L_write_register(ViPipe, 0x440e, 0x02); + sc2331_1L_write_register(ViPipe, 0x4509, 0x28); + sc2331_1L_write_register(ViPipe, 0x450d, 0x10); + sc2331_1L_write_register(ViPipe, 0x4819, 0x09); + sc2331_1L_write_register(ViPipe, 0x481b, 0x05); + sc2331_1L_write_register(ViPipe, 0x481d, 0x14); + sc2331_1L_write_register(ViPipe, 0x481f, 0x04); + sc2331_1L_write_register(ViPipe, 0x4821, 0x0a); + sc2331_1L_write_register(ViPipe, 0x4823, 0x05); + sc2331_1L_write_register(ViPipe, 0x4825, 0x04); + sc2331_1L_write_register(ViPipe, 0x4827, 0x05); + sc2331_1L_write_register(ViPipe, 0x4829, 0x08); + sc2331_1L_write_register(ViPipe, 0x5780, 0x66); + sc2331_1L_write_register(ViPipe, 0x578d, 0x40); + sc2331_1L_write_register(ViPipe, 0x5799, 0x06); + sc2331_1L_write_register(ViPipe, 0x36e9, 0x20); + sc2331_1L_write_register(ViPipe, 0x37f9, 0x27); + + sc2331_1L_default_reg_init(ViPipe); + + sc2331_1L_write_register(ViPipe, 0x0100, 0x01); + + // printf("ViPipe:%d,===SC2331_1L 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +void sc2331_1L_init(VI_PIPE ViPipe) +{ + sc2331_1L_i2c_init(ViPipe); + + //linear mode only + sc2331_1L_linear_1080p30_init(ViPipe); + + g_pastSC2331_1L[ViPipe]->bInit = CVI_TRUE; +} + +void sc2331_1L_exit(VI_PIPE ViPipe) +{ + sc2331_1L_i2c_exit(ViPipe); +} \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave/Makefile new file mode 100644 index 00000000..b9e50a17 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_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_sc2331_1L_slave.a +TARGET_SO = $(MW_LIB)/libsns_sc2331_1L_slave.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave/sc2331_1L_slave_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave/sc2331_1L_slave_cmos.c new file mode 100644 index 00000000..132e068b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave/sc2331_1L_slave_cmos.c @@ -0,0 +1,991 @@ +#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 "sc2331_1L_slave_cmos_ex.h" +#include "sc2331_1L_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 SC2331_1L_SLAVE_ID 0xCB5C +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC2331_1L_Slave[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC2331_1L_SLAVE_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC2331_1L_Slave[dev]) +#define SC2331_1L_SLAVE_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC2331_1L_Slave[dev] = pstCtx) +#define SC2331_1L_SLAVE_SENSOR_RESET_CTX(dev) (g_pastSC2331_1L_Slave[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC2331_1L_Slave_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC2331_1L_Slave_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC2331_1L_Slave_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc2331_Slave_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); +/*****SC2331_1L Lines Range*****/ +#define SC2331_1L_SLAVE_FULL_LINES_MAX (0x7FFF) + +/*****SC2331_1L Register Address*****/ +#define SC2331_1L_SLAVE_EXP_H_ADDR (0x3e00) +#define SC2331_1L_SLAVE_EXP_M_ADDR (0x3e01) +#define SC2331_1L_SLAVE_EXP_L_ADDR (0x3e02) + +#define SC2331_1L_SLAVE_AGAIN_H_ADDR (0x3e08) + +#define SC2331_1L_SLAVE_DGAIN_H_ADDR (0x3e06) +#define SC2331_1L_SLAVE_DGAIN_L_ADDR (0x3e07) + +#define SC2331_1L_SLAVE_VMAX_H_ADDR (0x320e) +#define SC2331_1L_SLAVE_VMAX_L_ADDR (0x320f) + +#define SC2331_1L_SLAVE_GAIN_DPC_ADDR (0x5799) +#define SC2331_1L_SLAVE_HOLD_ADDR (0x3812) + +#define SC2331_1L_SLAVE_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +#define SC2331_1L_SLAVE_EXPACCURACY (0.5) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC2331_1L_SLAVE_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC2331_1L_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC2331_1L_Slave_mode[pstSnsState->u8ImgMode]; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC2331_1L_SLAVE_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = SC2331_1L_SLAVE_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); + SC2331_1L_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC2331_1L_Slave_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC2331_1L_Slave_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC2331_1L_Slave_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC2331_1L_SLAVE_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 > SC2331_1L_SLAVE_FULL_LINES_MAX) ? SC2331_1L_SLAVE_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 - 13; + 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; + + SC2331_1L_SLAVE_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 = 2; + u32MaxTime = 2 * pstSnsState->au32FL[0] - 13; + 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[6] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 4064, + .idxBase = 64, + .regGain = 0x08, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 8128, + .idxBase = 128, + .regGain = 0x09, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 16256, + .idxBase = 192, + .regGain = 0x0b, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 32512, + .idxBase = 256, + .regGain = 0x0f, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 32768, + .idxBase = 320, + .regGain = 0x1f, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, +}; +static CVI_U32 Again_table[321] = { + 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, 32768 +}; + +static struct gain_tbl_info_s DgainInfo[3] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 4064, + .idxBase = 64, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 4096, + .idxBase = 128, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, +}; + +static CVI_U32 Dgain_table[129] = { + 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 +}; + +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[320]) { + *pu32AgainLin = Again_table[320]; + *pu32AgainDb = 320; + return CVI_SUCCESS; + } + + for (i = 1; i < 321; 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[128]) { + *pu32DgainLin = Dgain_table[128]; + *pu32DgainDb = 128; + return CVI_SUCCESS; + } + + for (i = 1; i < 129; 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; + + SC2331_1L_SLAVE_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); + + /* 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 SC2331_1L_SLAVE_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2331_1L_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC2331_1L_Slave_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; + + SC2331_1L_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC2331_1L_SLAVE_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC2331_1L_Slave_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); + SC2331_1L_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_aunSC2331_1L_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 = sc2331_1L_slave_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc2331_1L_slave_addr_byte; + pstI2c_data[i].u32DataByteNum = sc2331_1L_slave_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC2331_1L_SLAVE_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_M_ADDR].u32RegAddr = SC2331_1L_SLAVE_EXP_M_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC2331_1L_SLAVE_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H_ADDR].u32RegAddr = SC2331_1L_SLAVE_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L_ADDR].u32RegAddr = SC2331_1L_SLAVE_DGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC2331_1L_SLAVE_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC2331_1L_SLAVE_DGAIN_L_ADDR; + printf("awei pingbi\n"); + //pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC2331_1L_SLAVE_VMAX_H_ADDR; + //pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC2331_1L_SLAVE_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); + SC2331_1L_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 (SC2331_1L_SLAVE_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC2331_1L_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; + } + } + + 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; + + SC2331_1L_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeSc2331_Slave_MirrorFip[ViPipe] != eSnsMirrorFlip) { + sc2331_1L_slave_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeSc2331_Slave_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC2331_1L_SLAVE_MODE_S *pstMode = CVI_NULL; + + SC2331_1L_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC2331_1L_SLAVE_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC2331_1L_Slave_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; + + SC2331_1L_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc2331_1L_slave_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC2331_1L_Slave_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC2331_1L_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 = &sc2331_1L_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 = sc2331_1L_slave_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc2331_1L_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 sc2331_1L_slave_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC2331_1L_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; + + SC2331_1L_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)); + + SC2331_1L_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; + + SC2331_1L_SLAVE_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC2331_1L_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 = SC2331_1L_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, SC2331_1L_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, SC2331_1L_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, SC2331_1L_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_au16SC2331_1L_Slave_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC2331_1L_Slave_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC2331_1L_Slave_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc2331_1L_slave_standby, + .pfnRestart = sc2331_1L_slave_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = sc2331_1L_slave_write_register, + .pfnReadReg = sc2331_1L_slave_read_register, + .pfnSetBusInfo = sc2331_1L_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 = sc2331_1L_slave_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave/sc2331_1L_slave_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave/sc2331_1L_slave_cmos_ex.h new file mode 100644 index 00000000..ff41d6de --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave/sc2331_1L_slave_cmos_ex.h @@ -0,0 +1,80 @@ +#ifndef __SC2331_1L_SLAVE_CMOS_EX_H_ +#define __SC2331_1L_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 sc2331_1L_slave_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_REGS_NUM +}; + +typedef enum _SC2331_1L_SLAVE_MODE_E { + SC2331_1L_SLAVE_MODE_1920X1080P30 = 0, + SC2331_1L_SLAVE_MODE_LINEAR_NUM, + SC2331_1L_SLAVE_MODE_NUM +} SC2331_1L_SLAVE_MODE_E; + +typedef struct _SC2331_1L_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]; + char name[64]; +} SC2331_1L_SLAVE_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC2331_1L_Slave[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC2331_1L_Slave_BusInfo[]; +extern CVI_U16 g_au16SC2331_1L_GainMode[]; +extern CVI_U16 g_au16SC2331_1L_L2SMode[]; +extern const CVI_U8 sc2331_1L_slave_i2c_addr; +extern const CVI_U32 sc2331_1L_slave_addr_byte; +extern const CVI_U32 sc2331_1L_slave_data_byte; +extern void sc2331_1L_slave_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void sc2331_1L_slave_init(VI_PIPE ViPipe); +extern void sc2331_1L_slave_exit(VI_PIPE ViPipe); +extern void sc2331_1L_slave_standby(VI_PIPE ViPipe); +extern void sc2331_1L_slave_restart(VI_PIPE ViPipe); +extern int sc2331_1L_slave_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc2331_1L_slave_read_register(VI_PIPE ViPipe, int addr); +extern int sc2331_1L_slave_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC2331_1L_SLAVE_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave/sc2331_1L_slave_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave/sc2331_1L_slave_cmos_param.h new file mode 100644 index 00000000..13e8bd3b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave/sc2331_1L_slave_cmos_param.h @@ -0,0 +1,125 @@ +#ifndef __SC2331_1L_SLAVE_CMOS_PARAM_H_ +#define __SC2331_1L_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 "sc2331_1L_slave_cmos_ex.h" + +static const SC2331_1L_SLAVE_MODE_S g_astSC2331_1L_Slave_mode[SC2331_1L_SLAVE_MODE_NUM] = { + [SC2331_1L_SLAVE_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 / 0xFFFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 2,//3 + .u16Max = 1125 - 13, + .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 = {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 sc2331_1L_slave_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, -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 /* __SC2331_1L_SLAVE_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave/sc2331_1L_slave_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave/sc2331_1L_slave_sensor_ctl.c new file mode 100644 index 00000000..b9bc6fda --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave/sc2331_1L_slave_sensor_ctl.c @@ -0,0 +1,410 @@ +#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 "sc2331_1L_slave_cmos_ex.h" + +#define SC2331_1L_SLAVE_CHIP_ID_HI_ADDR 0x3107 +#define SC2331_1L_SLAVE_CHIP_ID_LO_ADDR 0x3108 +#define SC2331_1L_SLAVE_CHIP_ID 0xcb5c + +static void sc2331_1L_slave_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc2331_1L_slave_i2c_addr = 0x30; /* I2C Address of SC2331_1L */ +const CVI_U32 sc2331_1L_slave_addr_byte = 2; +const CVI_U32 sc2331_1L_slave_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc2331_1L_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_aunSC2331_1L_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/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc2331_1L_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 sc2331_1L_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 sc2331_1L_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 (sc2331_1L_slave_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc2331_1L_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, sc2331_1L_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 (sc2331_1L_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 sc2331_1L_slave_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 (sc2331_1L_slave_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc2331_1L_slave_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc2331_1L_slave_addr_byte + sc2331_1L_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 sc2331_1L_slave_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) + sc2331_1L_slave_write_register(ViPipe, addr, data); + } +} + +void sc2331_1L_slave_standby(VI_PIPE ViPipe) +{ + sc2331_1L_slave_write_register(ViPipe, 0x0100, 0x00); +} + +void sc2331_1L_slave_restart(VI_PIPE ViPipe) +{ + sc2331_1L_slave_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc2331_1L_slave_write_register(ViPipe, 0x0100, 0x01); +} + +void sc2331_1L_slave_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC2331_1L_Slave[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC2331_1L_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc2331_1L_slave_write_register(ViPipe, + g_pastSC2331_1L_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC2331_1L_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc2331_1L_slave_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; + } + + sc2331_1L_slave_write_register(ViPipe, 0x3221, val); +} + + +int sc2331_1L_slave_probe(VI_PIPE ViPipe) +{ +int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc2331_1L_slave_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc2331_1L_slave_read_register(ViPipe, SC2331_1L_SLAVE_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 = sc2331_1L_slave_read_register(ViPipe, SC2331_1L_SLAVE_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 != SC2331_1L_SLAVE_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + +// printf("======%d\n",ViPipe); + return CVI_SUCCESS; +} + + + +/* 1080P30 and 1080P25 */ +static void sc2331_1L_slave_linear_1080p30_init(VI_PIPE ViPipe) +{ + sc2331_1L_slave_write_register(ViPipe, 0x0103, 0x01); + sc2331_1L_slave_write_register(ViPipe, 0x0100, 0x00); + sc2331_1L_slave_write_register(ViPipe, 0x36e9, 0x80); + sc2331_1L_slave_write_register(ViPipe, 0x37f9, 0x80); + + sc2331_1L_slave_write_register(ViPipe, 0x300a, 0x24); + + sc2331_1L_slave_write_register(ViPipe, 0x3018, 0x1a); + sc2331_1L_slave_write_register(ViPipe, 0x3019, 0x0e); + sc2331_1L_slave_write_register(ViPipe, 0x301f, 0x20); + printf("awei 22 hao 14:15 sc2331_1L_slave\n"); + // sc2331_1L_slave_write_register(ViPipe, 0x320e, 0x04); + // sc2331_1L_slave_write_register(ViPipe, 0x320f, 0x65); + + sc2331_1L_slave_write_register(ViPipe, 0x320e, 0x04); + sc2331_1L_slave_write_register(ViPipe, 0x320f, 0x63); + + sc2331_1L_slave_write_register(ViPipe, 0x3222, 0x01); + sc2331_1L_slave_write_register(ViPipe, 0x3224, 0x82); + sc2331_1L_slave_write_register(ViPipe, 0x322e, 0x00); + sc2331_1L_slave_write_register(ViPipe, 0x322f, 0x02); + sc2331_1L_slave_write_register(ViPipe, 0x3230, 0x00); + sc2331_1L_slave_write_register(ViPipe, 0x3231, 0x04); + + sc2331_1L_slave_write_register(ViPipe, 0x3258, 0x0e); + sc2331_1L_slave_write_register(ViPipe, 0x3301, 0x06); + sc2331_1L_slave_write_register(ViPipe, 0x3302, 0x10); + sc2331_1L_slave_write_register(ViPipe, 0x3304, 0x68); + sc2331_1L_slave_write_register(ViPipe, 0x3306, 0x90); + sc2331_1L_slave_write_register(ViPipe, 0x3308, 0x18); + sc2331_1L_slave_write_register(ViPipe, 0x3309, 0x80); + sc2331_1L_slave_write_register(ViPipe, 0x330a, 0x01); + sc2331_1L_slave_write_register(ViPipe, 0x330b, 0x48); + sc2331_1L_slave_write_register(ViPipe, 0x330d, 0x18); + sc2331_1L_slave_write_register(ViPipe, 0x331c, 0x02); + sc2331_1L_slave_write_register(ViPipe, 0x331e, 0x59); + sc2331_1L_slave_write_register(ViPipe, 0x331f, 0x71); + sc2331_1L_slave_write_register(ViPipe, 0x3333, 0x10); + sc2331_1L_slave_write_register(ViPipe, 0x3334, 0x40); + sc2331_1L_slave_write_register(ViPipe, 0x3364, 0x56); + sc2331_1L_slave_write_register(ViPipe, 0x3390, 0x08); + sc2331_1L_slave_write_register(ViPipe, 0x3391, 0x09); + sc2331_1L_slave_write_register(ViPipe, 0x3392, 0x0b); + sc2331_1L_slave_write_register(ViPipe, 0x3393, 0x0a); + sc2331_1L_slave_write_register(ViPipe, 0x3394, 0x2a); + sc2331_1L_slave_write_register(ViPipe, 0x3395, 0x2a); + sc2331_1L_slave_write_register(ViPipe, 0x3396, 0x48); + sc2331_1L_slave_write_register(ViPipe, 0x3397, 0x49); + sc2331_1L_slave_write_register(ViPipe, 0x3398, 0x4b); + sc2331_1L_slave_write_register(ViPipe, 0x3399, 0x06); + sc2331_1L_slave_write_register(ViPipe, 0x339a, 0x0a); + sc2331_1L_slave_write_register(ViPipe, 0x339b, 0x30); + sc2331_1L_slave_write_register(ViPipe, 0x339c, 0x48); + sc2331_1L_slave_write_register(ViPipe, 0x33ad, 0x2c); + sc2331_1L_slave_write_register(ViPipe, 0x33ae, 0x38); + sc2331_1L_slave_write_register(ViPipe, 0x33b3, 0x40); + sc2331_1L_slave_write_register(ViPipe, 0x349f, 0x02); + sc2331_1L_slave_write_register(ViPipe, 0x34a6, 0x09); + sc2331_1L_slave_write_register(ViPipe, 0x34a7, 0x0f); + sc2331_1L_slave_write_register(ViPipe, 0x34a8, 0x30); + sc2331_1L_slave_write_register(ViPipe, 0x34a9, 0x28); + sc2331_1L_slave_write_register(ViPipe, 0x34f8, 0x5f); + sc2331_1L_slave_write_register(ViPipe, 0x34f9, 0x28); + sc2331_1L_slave_write_register(ViPipe, 0x3630, 0xc6); + sc2331_1L_slave_write_register(ViPipe, 0x3633, 0x33); + sc2331_1L_slave_write_register(ViPipe, 0x3637, 0x6b); + sc2331_1L_slave_write_register(ViPipe, 0x363c, 0xc1); + sc2331_1L_slave_write_register(ViPipe, 0x363e, 0xc2); + + printf("xiugai 2 14:50\n"); + sc2331_1L_slave_write_register(ViPipe, 0x3650, 0x33); + sc2331_1L_slave_write_register(ViPipe, 0x3651, 0x7f); + + sc2331_1L_slave_write_register(ViPipe, 0x3670, 0x2e); + sc2331_1L_slave_write_register(ViPipe, 0x3674, 0xc5); + sc2331_1L_slave_write_register(ViPipe, 0x3675, 0xc7); + sc2331_1L_slave_write_register(ViPipe, 0x3676, 0xcb); + sc2331_1L_slave_write_register(ViPipe, 0x3677, 0x44); + sc2331_1L_slave_write_register(ViPipe, 0x3678, 0x48); + sc2331_1L_slave_write_register(ViPipe, 0x3679, 0x48); + sc2331_1L_slave_write_register(ViPipe, 0x367c, 0x08); + sc2331_1L_slave_write_register(ViPipe, 0x367d, 0x0b); + sc2331_1L_slave_write_register(ViPipe, 0x367e, 0x0b); + sc2331_1L_slave_write_register(ViPipe, 0x367f, 0x0f); + sc2331_1L_slave_write_register(ViPipe, 0x3690, 0x33); + sc2331_1L_slave_write_register(ViPipe, 0x3691, 0x33); + sc2331_1L_slave_write_register(ViPipe, 0x3692, 0x33); + sc2331_1L_slave_write_register(ViPipe, 0x3693, 0x84); + sc2331_1L_slave_write_register(ViPipe, 0x3694, 0x85); + sc2331_1L_slave_write_register(ViPipe, 0x3695, 0x8d); + sc2331_1L_slave_write_register(ViPipe, 0x3696, 0x9c); + sc2331_1L_slave_write_register(ViPipe, 0x369c, 0x0b); + sc2331_1L_slave_write_register(ViPipe, 0x369d, 0x0f); + sc2331_1L_slave_write_register(ViPipe, 0x369e, 0x09); + sc2331_1L_slave_write_register(ViPipe, 0x369f, 0x0b); + sc2331_1L_slave_write_register(ViPipe, 0x36a0, 0x0f); + sc2331_1L_slave_write_register(ViPipe, 0x36ec, 0x0c); + sc2331_1L_slave_write_register(ViPipe, 0x370f, 0x01); + sc2331_1L_slave_write_register(ViPipe, 0x3722, 0x05); + sc2331_1L_slave_write_register(ViPipe, 0x3724, 0x20); + sc2331_1L_slave_write_register(ViPipe, 0x3725, 0x91); + sc2331_1L_slave_write_register(ViPipe, 0x3771, 0x05); + sc2331_1L_slave_write_register(ViPipe, 0x3772, 0x05); + sc2331_1L_slave_write_register(ViPipe, 0x3773, 0x05); + sc2331_1L_slave_write_register(ViPipe, 0x377a, 0x0b); + sc2331_1L_slave_write_register(ViPipe, 0x377b, 0x0f); + sc2331_1L_slave_write_register(ViPipe, 0x3900, 0x19); + sc2331_1L_slave_write_register(ViPipe, 0x3905, 0xb8); + sc2331_1L_slave_write_register(ViPipe, 0x391b, 0x80); + sc2331_1L_slave_write_register(ViPipe, 0x391c, 0x04); + sc2331_1L_slave_write_register(ViPipe, 0x391d, 0x81); + sc2331_1L_slave_write_register(ViPipe, 0x3933, 0xc0); + sc2331_1L_slave_write_register(ViPipe, 0x3934, 0x08); + sc2331_1L_slave_write_register(ViPipe, 0x3940, 0x72); + sc2331_1L_slave_write_register(ViPipe, 0x3941, 0x00); + sc2331_1L_slave_write_register(ViPipe, 0x3942, 0x00); + sc2331_1L_slave_write_register(ViPipe, 0x3943, 0x09); + sc2331_1L_slave_write_register(ViPipe, 0x3946, 0x10); + sc2331_1L_slave_write_register(ViPipe, 0x3957, 0x86); + sc2331_1L_slave_write_register(ViPipe, 0x3e01, 0x8b); + sc2331_1L_slave_write_register(ViPipe, 0x3e02, 0xd0); + sc2331_1L_slave_write_register(ViPipe, 0x3e08, 0x00); + sc2331_1L_slave_write_register(ViPipe, 0x440e, 0x02); + sc2331_1L_slave_write_register(ViPipe, 0x4509, 0x28); + sc2331_1L_slave_write_register(ViPipe, 0x450d, 0x10); + sc2331_1L_slave_write_register(ViPipe, 0x4819, 0x09); + sc2331_1L_slave_write_register(ViPipe, 0x481b, 0x05); + sc2331_1L_slave_write_register(ViPipe, 0x481d, 0x14); + sc2331_1L_slave_write_register(ViPipe, 0x481f, 0x04); + sc2331_1L_slave_write_register(ViPipe, 0x4821, 0x0a); + sc2331_1L_slave_write_register(ViPipe, 0x4823, 0x05); + sc2331_1L_slave_write_register(ViPipe, 0x4825, 0x04); + sc2331_1L_slave_write_register(ViPipe, 0x4827, 0x05); + sc2331_1L_slave_write_register(ViPipe, 0x4829, 0x08); + sc2331_1L_slave_write_register(ViPipe, 0x5780, 0x66); + sc2331_1L_slave_write_register(ViPipe, 0x578d, 0x40); + sc2331_1L_slave_write_register(ViPipe, 0x5799, 0x06); + sc2331_1L_slave_write_register(ViPipe, 0x36e9, 0x20); + sc2331_1L_slave_write_register(ViPipe, 0x37f9, 0x27); + + sc2331_1L_slave_default_reg_init(ViPipe); + + sc2331_1L_slave_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC2331_1L 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +void sc2331_1L_slave_init(VI_PIPE ViPipe) +{ + sc2331_1L_slave_i2c_init(ViPipe); + + //linear mode only + sc2331_1L_slave_linear_1080p30_init(ViPipe); + + g_pastSC2331_1L_Slave[ViPipe]->bInit = CVI_TRUE; +} + +void sc2331_1L_slave_exit(VI_PIPE ViPipe) +{ + sc2331_1L_slave_i2c_exit(ViPipe); +} \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave1/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave1/Makefile new file mode 100644 index 00000000..1b39a5b3 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave1/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_sc2331_1L_slave1.a +TARGET_SO = $(MW_LIB)/libsns_sc2331_1L_slave1.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave1/sc2331_1L_slave1_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave1/sc2331_1L_slave1_cmos.c new file mode 100644 index 00000000..17824be1 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave1/sc2331_1L_slave1_cmos.c @@ -0,0 +1,991 @@ +#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 "sc2331_1L_slave1_cmos_ex.h" +#include "sc2331_1L_slave1_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 SC2331_1L_slave1_ID 0xCB5C +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC2331_1L_slave1[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC2331_1L_slave1_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC2331_1L_slave1[dev]) +#define SC2331_1L_slave1_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC2331_1L_slave1[dev] = pstCtx) +#define SC2331_1L_slave1_SENSOR_RESET_CTX(dev) (g_pastSC2331_1L_slave1[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC2331_1L_slave1_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC2331_1L_slave1_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC2331_1L_slave1_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc2331_slave1_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); +/*****SC2331_1L Lines Range*****/ +#define SC2331_1L_slave1_FULL_LINES_MAX (0x7FFF) + +/*****SC2331_1L Register Address*****/ +#define SC2331_1L_slave1_EXP_H_ADDR (0x3e00) +#define SC2331_1L_slave1_EXP_M_ADDR (0x3e01) +#define SC2331_1L_slave1_EXP_L_ADDR (0x3e02) + +#define SC2331_1L_slave1_AGAIN_H_ADDR (0x3e08) + +#define SC2331_1L_slave1_DGAIN_H_ADDR (0x3e06) +#define SC2331_1L_slave1_DGAIN_L_ADDR (0x3e07) + +#define SC2331_1L_slave1_VMAX_H_ADDR (0x320e) +#define SC2331_1L_slave1_VMAX_L_ADDR (0x320f) + +#define SC2331_1L_slave1_GAIN_DPC_ADDR (0x5799) +#define SC2331_1L_slave1_HOLD_ADDR (0x3812) + +#define SC2331_1L_slave1_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080) + +#define SC2331_1L_slave1_EXPACCURACY (0.5) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC2331_1L_slave1_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC2331_1L_slave1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC2331_1L_slave1_mode[pstSnsState->u8ImgMode]; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC2331_1L_slave1_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = SC2331_1L_slave1_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); + SC2331_1L_slave1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC2331_1L_slave1_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC2331_1L_slave1_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC2331_1L_slave1_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC2331_1L_slave1_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 > SC2331_1L_slave1_FULL_LINES_MAX) ? SC2331_1L_slave1_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 - 13; + 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; + + SC2331_1L_slave1_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 = 2; + u32MaxTime = 2 * pstSnsState->au32FL[0] - 13; + 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[6] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 4064, + .idxBase = 64, + .regGain = 0x08, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 8128, + .idxBase = 128, + .regGain = 0x09, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 16256, + .idxBase = 192, + .regGain = 0x0b, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 32512, + .idxBase = 256, + .regGain = 0x0f, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 32768, + .idxBase = 320, + .regGain = 0x1f, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, +}; +static CVI_U32 Again_table[321] = { + 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, 32768 +}; + +static struct gain_tbl_info_s DgainInfo[3] = { + { + .gainMax = 2031, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 4064, + .idxBase = 64, + .regGain = 0x01, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, + { + .gainMax = 4096, + .idxBase = 128, + .regGain = 0x03, + .regGainFineBase = 0x80, + .regGainFineStep = 2, + }, +}; + +static CVI_U32 Dgain_table[129] = { + 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 +}; + +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[320]) { + *pu32AgainLin = Again_table[320]; + *pu32AgainDb = 320; + return CVI_SUCCESS; + } + + for (i = 1; i < 321; 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[128]) { + *pu32DgainLin = Dgain_table[128]; + *pu32DgainDb = 128; + return CVI_SUCCESS; + } + + for (i = 1; i < 129; 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; + + SC2331_1L_slave1_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); + + /* 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 SC2331_1L_slave1_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2331_1L_slave1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC2331_1L_slave1_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; + + SC2331_1L_slave1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC2331_1L_slave1_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC2331_1L_slave1_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); + SC2331_1L_slave1_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_aunSC2331_1L_slave1_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 = sc2331_1L_slave1_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc2331_1L_slave1_addr_byte; + pstI2c_data[i].u32DataByteNum = sc2331_1L_slave1_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC2331_1L_slave1_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_M_ADDR].u32RegAddr = SC2331_1L_slave1_EXP_M_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC2331_1L_slave1_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_H_ADDR].u32RegAddr = SC2331_1L_slave1_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_L_ADDR].u32RegAddr = SC2331_1L_slave1_DGAIN_L_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC2331_1L_slave1_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC2331_1L_slave1_DGAIN_L_ADDR; + printf("awei pingbi2\n"); + // pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC2331_1L_slave1_VMAX_H_ADDR; + // pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC2331_1L_slave1_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); + SC2331_1L_slave1_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 (SC2331_1L_slave1_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC2331_1L_slave1_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; + + SC2331_1L_slave1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeSc2331_slave1_MirrorFip[ViPipe] != eSnsMirrorFlip) { + sc2331_1L_slave1_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeSc2331_slave1_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC2331_1L_slave1_MODE_S *pstMode = CVI_NULL; + + SC2331_1L_slave1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC2331_1L_slave1_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC2331_1L_slave1_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; + + SC2331_1L_slave1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc2331_1L_slave1_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC2331_1L_slave1_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC2331_1L_slave1_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 = &sc2331_1L_slave1_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 = sc2331_1L_slave1_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc2331_1L_slave1_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 sc2331_1L_slave1_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC2331_1L_slave1_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC2331_1L_slave1_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)); + + SC2331_1L_slave1_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC2331_1L_slave1_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC2331_1L_slave1_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 = SC2331_1L_slave1_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, SC2331_1L_slave1_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, SC2331_1L_slave1_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, SC2331_1L_slave1_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_au16SC2331_1L_slave1_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC2331_1L_slave1_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC2331_1L_Slave1_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc2331_1L_slave1_standby, + .pfnRestart = sc2331_1L_slave1_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = sc2331_1L_slave1_write_register, + .pfnReadReg = sc2331_1L_slave1_read_register, + .pfnSetBusInfo = sc2331_1L_slave1_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 = sc2331_1L_slave1_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave1/sc2331_1L_slave1_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave1/sc2331_1L_slave1_cmos_ex.h new file mode 100644 index 00000000..eb7bcb91 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave1/sc2331_1L_slave1_cmos_ex.h @@ -0,0 +1,80 @@ +#ifndef __SC2331_1L_slave1_CMOS_EX_H_ +#define __SC2331_1L_slave1_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 sc2331_1L_slave1_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_REGS_NUM +}; + +typedef enum _SC2331_1L_slave1_MODE_E { + SC2331_1L_slave1_MODE_1920X1080P30 = 0, + SC2331_1L_slave1_MODE_LINEAR_NUM, + SC2331_1L_slave1_MODE_NUM +} SC2331_1L_slave1_MODE_E; + +typedef struct _SC2331_1L_slave1_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]; +} SC2331_1L_slave1_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC2331_1L_slave1[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC2331_1L_slave1_BusInfo[]; +extern CVI_U16 g_au16SC2331_1L_GainMode[]; +extern CVI_U16 g_au16SC2331_1L_L2SMode[]; +extern const CVI_U8 sc2331_1L_slave1_i2c_addr; +extern const CVI_U32 sc2331_1L_slave1_addr_byte; +extern const CVI_U32 sc2331_1L_slave1_data_byte; +extern void sc2331_1L_slave1_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void sc2331_1L_slave1_init(VI_PIPE ViPipe); +extern void sc2331_1L_slave1_exit(VI_PIPE ViPipe); +extern void sc2331_1L_slave1_standby(VI_PIPE ViPipe); +extern void sc2331_1L_slave1_restart(VI_PIPE ViPipe); +extern int sc2331_1L_slave1_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc2331_1L_slave1_read_register(VI_PIPE ViPipe, int addr); +extern int sc2331_1L_slave1_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC2331_1L_slave1_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave1/sc2331_1L_slave1_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave1/sc2331_1L_slave1_cmos_param.h new file mode 100644 index 00000000..bf79c134 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave1/sc2331_1L_slave1_cmos_param.h @@ -0,0 +1,125 @@ +#ifndef __SC2331_1L_slave1_CMOS_PARAM_H_ +#define __SC2331_1L_slave1_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 "sc2331_1L_slave1_cmos_ex.h" + +static const SC2331_1L_slave1_MODE_S g_astSC2331_1L_slave1_mode[SC2331_1L_slave1_MODE_NUM] = { + [SC2331_1L_slave1_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 / 0xFFFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 2,//3 + .u16Max = 1125 - 13, + .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 = {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 sc2331_1L_slave1_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, -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 /* __SC2331_1L_slave1_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave1/sc2331_1L_slave1_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave1/sc2331_1L_slave1_sensor_ctl.c new file mode 100644 index 00000000..dcf98663 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2331_1L_slave1/sc2331_1L_slave1_sensor_ctl.c @@ -0,0 +1,410 @@ +#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 "sc2331_1L_slave1_cmos_ex.h" + +#define SC2331_1L_slave1_CHIP_ID_HI_ADDR 0x3107 +#define SC2331_1L_slave1_CHIP_ID_LO_ADDR 0x3108 +#define SC2331_1L_slave1_CHIP_ID 0xcb5c + +static void sc2331_1L_slave1_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc2331_1L_slave1_i2c_addr = 0x30; /* I2C Address of SC2331_1L */ +const CVI_U32 sc2331_1L_slave1_addr_byte = 2; +const CVI_U32 sc2331_1L_slave1_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc2331_1L_slave1_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC2331_1L_slave1_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, sc2331_1L_slave1_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 sc2331_1L_slave1_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 sc2331_1L_slave1_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 (sc2331_1L_slave1_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc2331_1L_slave1_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, sc2331_1L_slave1_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc2331_1L_slave1_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 sc2331_1L_slave1_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 (sc2331_1L_slave1_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc2331_1L_slave1_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc2331_1L_slave1_addr_byte + sc2331_1L_slave1_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 sc2331_1L_slave1_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) + sc2331_1L_slave1_write_register(ViPipe, addr, data); + } +} + +void sc2331_1L_slave1_standby(VI_PIPE ViPipe) +{ + sc2331_1L_slave1_write_register(ViPipe, 0x0100, 0x00); +} + +void sc2331_1L_slave1_restart(VI_PIPE ViPipe) +{ + sc2331_1L_slave1_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc2331_1L_slave1_write_register(ViPipe, 0x0100, 0x01); +} + +void sc2331_1L_slave1_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC2331_1L_slave1[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC2331_1L_slave1[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc2331_1L_slave1_write_register(ViPipe, + g_pastSC2331_1L_slave1[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC2331_1L_slave1[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc2331_1L_slave1_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; + } + + sc2331_1L_slave1_write_register(ViPipe, 0x3221, val); +} + + +int sc2331_1L_slave1_probe(VI_PIPE ViPipe) +{ +int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc2331_1L_slave1_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc2331_1L_slave1_read_register(ViPipe, SC2331_1L_slave1_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 = sc2331_1L_slave1_read_register(ViPipe, SC2331_1L_slave1_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 != SC2331_1L_slave1_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + +// printf("======%d\n",ViPipe); + return CVI_SUCCESS; +} + + + +/* 1080P30 and 1080P25 */ +static void sc2331_1L_slave1_linear_1080p30_init(VI_PIPE ViPipe) +{ + sc2331_1L_slave1_write_register(ViPipe, 0x0103, 0x01); + sc2331_1L_slave1_write_register(ViPipe, 0x0100, 0x00); + sc2331_1L_slave1_write_register(ViPipe, 0x36e9, 0x80); + sc2331_1L_slave1_write_register(ViPipe, 0x37f9, 0x80); + + sc2331_1L_slave1_write_register(ViPipe, 0x300a, 0x24); + + sc2331_1L_slave1_write_register(ViPipe, 0x3018, 0x1a); + sc2331_1L_slave1_write_register(ViPipe, 0x3019, 0x0e); + sc2331_1L_slave1_write_register(ViPipe, 0x301f, 0x20); + printf("awei 22 hao 14:15 sc2331_1L_slave1\n"); + // sc2331_1L_slave1_write_register(ViPipe, 0x320e, 0x04); + // sc2331_1L_slave1_write_register(ViPipe, 0x320f, 0x65); + + sc2331_1L_slave1_write_register(ViPipe, 0x320e, 0x04); + sc2331_1L_slave1_write_register(ViPipe, 0x320f, 0x63); + + sc2331_1L_slave1_write_register(ViPipe, 0x3222, 0x01); + sc2331_1L_slave1_write_register(ViPipe, 0x3224, 0x82); + sc2331_1L_slave1_write_register(ViPipe, 0x322e, 0x00); + sc2331_1L_slave1_write_register(ViPipe, 0x322f, 0x02); + sc2331_1L_slave1_write_register(ViPipe, 0x3230, 0x00); + sc2331_1L_slave1_write_register(ViPipe, 0x3231, 0x04); + + sc2331_1L_slave1_write_register(ViPipe, 0x3258, 0x0e); + sc2331_1L_slave1_write_register(ViPipe, 0x3301, 0x06); + sc2331_1L_slave1_write_register(ViPipe, 0x3302, 0x10); + sc2331_1L_slave1_write_register(ViPipe, 0x3304, 0x68); + sc2331_1L_slave1_write_register(ViPipe, 0x3306, 0x90); + sc2331_1L_slave1_write_register(ViPipe, 0x3308, 0x18); + sc2331_1L_slave1_write_register(ViPipe, 0x3309, 0x80); + sc2331_1L_slave1_write_register(ViPipe, 0x330a, 0x01); + sc2331_1L_slave1_write_register(ViPipe, 0x330b, 0x48); + sc2331_1L_slave1_write_register(ViPipe, 0x330d, 0x18); + sc2331_1L_slave1_write_register(ViPipe, 0x331c, 0x02); + sc2331_1L_slave1_write_register(ViPipe, 0x331e, 0x59); + sc2331_1L_slave1_write_register(ViPipe, 0x331f, 0x71); + sc2331_1L_slave1_write_register(ViPipe, 0x3333, 0x10); + sc2331_1L_slave1_write_register(ViPipe, 0x3334, 0x40); + sc2331_1L_slave1_write_register(ViPipe, 0x3364, 0x56); + sc2331_1L_slave1_write_register(ViPipe, 0x3390, 0x08); + sc2331_1L_slave1_write_register(ViPipe, 0x3391, 0x09); + sc2331_1L_slave1_write_register(ViPipe, 0x3392, 0x0b); + sc2331_1L_slave1_write_register(ViPipe, 0x3393, 0x0a); + sc2331_1L_slave1_write_register(ViPipe, 0x3394, 0x2a); + sc2331_1L_slave1_write_register(ViPipe, 0x3395, 0x2a); + sc2331_1L_slave1_write_register(ViPipe, 0x3396, 0x48); + sc2331_1L_slave1_write_register(ViPipe, 0x3397, 0x49); + sc2331_1L_slave1_write_register(ViPipe, 0x3398, 0x4b); + sc2331_1L_slave1_write_register(ViPipe, 0x3399, 0x06); + sc2331_1L_slave1_write_register(ViPipe, 0x339a, 0x0a); + sc2331_1L_slave1_write_register(ViPipe, 0x339b, 0x30); + sc2331_1L_slave1_write_register(ViPipe, 0x339c, 0x48); + sc2331_1L_slave1_write_register(ViPipe, 0x33ad, 0x2c); + sc2331_1L_slave1_write_register(ViPipe, 0x33ae, 0x38); + sc2331_1L_slave1_write_register(ViPipe, 0x33b3, 0x40); + sc2331_1L_slave1_write_register(ViPipe, 0x349f, 0x02); + sc2331_1L_slave1_write_register(ViPipe, 0x34a6, 0x09); + sc2331_1L_slave1_write_register(ViPipe, 0x34a7, 0x0f); + sc2331_1L_slave1_write_register(ViPipe, 0x34a8, 0x30); + sc2331_1L_slave1_write_register(ViPipe, 0x34a9, 0x28); + sc2331_1L_slave1_write_register(ViPipe, 0x34f8, 0x5f); + sc2331_1L_slave1_write_register(ViPipe, 0x34f9, 0x28); + sc2331_1L_slave1_write_register(ViPipe, 0x3630, 0xc6); + sc2331_1L_slave1_write_register(ViPipe, 0x3633, 0x33); + sc2331_1L_slave1_write_register(ViPipe, 0x3637, 0x6b); + sc2331_1L_slave1_write_register(ViPipe, 0x363c, 0xc1); + sc2331_1L_slave1_write_register(ViPipe, 0x363e, 0xc2); + + printf("xiugai 2 14:50\n"); + sc2331_1L_slave1_write_register(ViPipe, 0x3650, 0x33); + sc2331_1L_slave1_write_register(ViPipe, 0x3651, 0x7f); + + sc2331_1L_slave1_write_register(ViPipe, 0x3670, 0x2e); + sc2331_1L_slave1_write_register(ViPipe, 0x3674, 0xc5); + sc2331_1L_slave1_write_register(ViPipe, 0x3675, 0xc7); + sc2331_1L_slave1_write_register(ViPipe, 0x3676, 0xcb); + sc2331_1L_slave1_write_register(ViPipe, 0x3677, 0x44); + sc2331_1L_slave1_write_register(ViPipe, 0x3678, 0x48); + sc2331_1L_slave1_write_register(ViPipe, 0x3679, 0x48); + sc2331_1L_slave1_write_register(ViPipe, 0x367c, 0x08); + sc2331_1L_slave1_write_register(ViPipe, 0x367d, 0x0b); + sc2331_1L_slave1_write_register(ViPipe, 0x367e, 0x0b); + sc2331_1L_slave1_write_register(ViPipe, 0x367f, 0x0f); + sc2331_1L_slave1_write_register(ViPipe, 0x3690, 0x33); + sc2331_1L_slave1_write_register(ViPipe, 0x3691, 0x33); + sc2331_1L_slave1_write_register(ViPipe, 0x3692, 0x33); + sc2331_1L_slave1_write_register(ViPipe, 0x3693, 0x84); + sc2331_1L_slave1_write_register(ViPipe, 0x3694, 0x85); + sc2331_1L_slave1_write_register(ViPipe, 0x3695, 0x8d); + sc2331_1L_slave1_write_register(ViPipe, 0x3696, 0x9c); + sc2331_1L_slave1_write_register(ViPipe, 0x369c, 0x0b); + sc2331_1L_slave1_write_register(ViPipe, 0x369d, 0x0f); + sc2331_1L_slave1_write_register(ViPipe, 0x369e, 0x09); + sc2331_1L_slave1_write_register(ViPipe, 0x369f, 0x0b); + sc2331_1L_slave1_write_register(ViPipe, 0x36a0, 0x0f); + sc2331_1L_slave1_write_register(ViPipe, 0x36ec, 0x0c); + sc2331_1L_slave1_write_register(ViPipe, 0x370f, 0x01); + sc2331_1L_slave1_write_register(ViPipe, 0x3722, 0x05); + sc2331_1L_slave1_write_register(ViPipe, 0x3724, 0x20); + sc2331_1L_slave1_write_register(ViPipe, 0x3725, 0x91); + sc2331_1L_slave1_write_register(ViPipe, 0x3771, 0x05); + sc2331_1L_slave1_write_register(ViPipe, 0x3772, 0x05); + sc2331_1L_slave1_write_register(ViPipe, 0x3773, 0x05); + sc2331_1L_slave1_write_register(ViPipe, 0x377a, 0x0b); + sc2331_1L_slave1_write_register(ViPipe, 0x377b, 0x0f); + sc2331_1L_slave1_write_register(ViPipe, 0x3900, 0x19); + sc2331_1L_slave1_write_register(ViPipe, 0x3905, 0xb8); + sc2331_1L_slave1_write_register(ViPipe, 0x391b, 0x80); + sc2331_1L_slave1_write_register(ViPipe, 0x391c, 0x04); + sc2331_1L_slave1_write_register(ViPipe, 0x391d, 0x81); + sc2331_1L_slave1_write_register(ViPipe, 0x3933, 0xc0); + sc2331_1L_slave1_write_register(ViPipe, 0x3934, 0x08); + sc2331_1L_slave1_write_register(ViPipe, 0x3940, 0x72); + sc2331_1L_slave1_write_register(ViPipe, 0x3941, 0x00); + sc2331_1L_slave1_write_register(ViPipe, 0x3942, 0x00); + sc2331_1L_slave1_write_register(ViPipe, 0x3943, 0x09); + sc2331_1L_slave1_write_register(ViPipe, 0x3946, 0x10); + sc2331_1L_slave1_write_register(ViPipe, 0x3957, 0x86); + sc2331_1L_slave1_write_register(ViPipe, 0x3e01, 0x8b); + sc2331_1L_slave1_write_register(ViPipe, 0x3e02, 0xd0); + sc2331_1L_slave1_write_register(ViPipe, 0x3e08, 0x00); + sc2331_1L_slave1_write_register(ViPipe, 0x440e, 0x02); + sc2331_1L_slave1_write_register(ViPipe, 0x4509, 0x28); + sc2331_1L_slave1_write_register(ViPipe, 0x450d, 0x10); + sc2331_1L_slave1_write_register(ViPipe, 0x4819, 0x09); + sc2331_1L_slave1_write_register(ViPipe, 0x481b, 0x05); + sc2331_1L_slave1_write_register(ViPipe, 0x481d, 0x14); + sc2331_1L_slave1_write_register(ViPipe, 0x481f, 0x04); + sc2331_1L_slave1_write_register(ViPipe, 0x4821, 0x0a); + sc2331_1L_slave1_write_register(ViPipe, 0x4823, 0x05); + sc2331_1L_slave1_write_register(ViPipe, 0x4825, 0x04); + sc2331_1L_slave1_write_register(ViPipe, 0x4827, 0x05); + sc2331_1L_slave1_write_register(ViPipe, 0x4829, 0x08); + sc2331_1L_slave1_write_register(ViPipe, 0x5780, 0x66); + sc2331_1L_slave1_write_register(ViPipe, 0x578d, 0x40); + sc2331_1L_slave1_write_register(ViPipe, 0x5799, 0x06); + sc2331_1L_slave1_write_register(ViPipe, 0x36e9, 0x20); + sc2331_1L_slave1_write_register(ViPipe, 0x37f9, 0x27); + + sc2331_1L_slave1_default_reg_init(ViPipe); + + sc2331_1L_slave1_write_register(ViPipe, 0x0100, 0x01); + + // printf("ViPipe:%d,===SC2331_1L 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +void sc2331_1L_slave1_init(VI_PIPE ViPipe) +{ + sc2331_1L_slave1_i2c_init(ViPipe); + + //linear mode only + sc2331_1L_slave1_linear_1080p30_init(ViPipe); + + g_pastSC2331_1L_slave1[ViPipe]->bInit = CVI_TRUE; +} + +void sc2331_1L_slave1_exit(VI_PIPE ViPipe) +{ + sc2331_1L_slave1_i2c_exit(ViPipe); +} \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2335/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2335/Makefile new file mode 100644 index 00000000..8bd9dde4 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2335/sc2335_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2335/sc2335_cmos.c new file mode 100644 index 00000000..372e2b98 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2335/sc2335_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2335/sc2335_cmos_ex.h new file mode 100644 index 00000000..d2b7d224 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2335/sc2335_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2335/sc2335_cmos_param.h new file mode 100644 index 00000000..3f55de1a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2335/sc2335_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2335/sc2335_sensor_ctl.c new file mode 100644 index 00000000..8ac4d16f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336/Makefile new file mode 100644 index 00000000..cfab5277 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336/sc2336_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336/sc2336_cmos.c new file mode 100644 index 00000000..19d4d014 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336/sc2336_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336/sc2336_cmos_ex.h new file mode 100644 index 00000000..88eb624c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336/sc2336_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336/sc2336_cmos_param.h new file mode 100644 index 00000000..1825ccbd --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336/sc2336_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336/sc2336_sensor_ctl.c new file mode 100644 index 00000000..d1d446a8 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336/sc2336_sensor_ctl.c @@ -0,0 +1,434 @@ +#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, 0x300a, 0x24); + sc2336_write_register(ViPipe, 0x301f, 0xa9); + sc2336_write_register(ViPipe, 0x3032, 0xa0); + sc2336_write_register(ViPipe, 0x3106, 0x05); + sc2336_write_register(ViPipe, 0x320c, 0x08); + sc2336_write_register(ViPipe, 0x320d, 0x4a); + sc2336_write_register(ViPipe, 0x320e, 0x04); + sc2336_write_register(ViPipe, 0x320f, 0x6b); + sc2336_write_register(ViPipe, 0x322e, 0x04); + sc2336_write_register(ViPipe, 0x322f, 0x67); + 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, 0x78); + sc2336_write_register(ViPipe, 0x33fb, 0xd8); + 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, 0x28); + sc2336_write_register(ViPipe, 0x34ac, 0x01); + sc2336_write_register(ViPipe, 0x34ad, 0x90); + 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, 0x22); + sc2336_write_register(ViPipe, 0x3691, 0x22); + sc2336_write_register(ViPipe, 0x3692, 0x22); + 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, 0x36ea, 0x08); + sc2336_write_register(ViPipe, 0x36eb, 0x0c); + sc2336_write_register(ViPipe, 0x36ec, 0x1c); + sc2336_write_register(ViPipe, 0x36ed, 0x28); + 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, 0x37fa, 0x08); + sc2336_write_register(ViPipe, 0x37fb, 0x32); + sc2336_write_register(ViPipe, 0x37fc, 0x11); + sc2336_write_register(ViPipe, 0x37fd, 0x37); + 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, 0x46); + sc2336_write_register(ViPipe, 0x3e02, 0x50); + 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, 0x4819, 0x05); + sc2336_write_register(ViPipe, 0x481b, 0x03); + sc2336_write_register(ViPipe, 0x481d, 0x0a); + sc2336_write_register(ViPipe, 0x481f, 0x02); + sc2336_write_register(ViPipe, 0x4821, 0x08); + sc2336_write_register(ViPipe, 0x4823, 0x03); + sc2336_write_register(ViPipe, 0x4825, 0x02); + sc2336_write_register(ViPipe, 0x4827, 0x03); + sc2336_write_register(ViPipe, 0x4829, 0x04); + 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, 0x44); + sc2336_write_register(ViPipe, 0x37f9, 0x44); + 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_1L/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_1L/Makefile new file mode 100644 index 00000000..4d5a252f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_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_sc2336_1l.a +TARGET_SO = $(MW_LIB)/libsns_sc2336_1l.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_1L/sc2336_1L_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_1L/sc2336_1L_cmos.c new file mode 100644 index 00000000..cb7bb261 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_1L/sc2336_1L_cmos.c @@ -0,0 +1,905 @@ +#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_1L_cmos_ex.h" +#include "sc2336_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 SC2336_1L_ID 35 +#define SENSOR_SC2336_1L_WIDTH 1920 +#define SENSOR_SC2336_1L_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC2336_1L[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC2336_1L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC2336_1L[dev]) +#define SC2336_1L_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC2336_1L[dev] = pstCtx) +#define SC2336_1L_SENSOR_RESET_CTX(dev) (g_pastSC2336_1L[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC2336_1L_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC2336_1L_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC2336_1L_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +SC2336_1L_STATE_S g_astSC2336_1L_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_1L Lines Range*****/ +#define SC2336_1L_FULL_LINES_MAX (0xFFFF) + +/*****SC2336_1L Register Address*****/ +#define SC2336_1L_SHS1_0_ADDR 0x3E00 +#define SC2336_1L_SHS1_1_ADDR 0x3E01 +#define SC2336_1L_SHS1_2_ADDR 0x3E02 +#define SC2336_1L_AGAIN0_ADDR 0x3E09 +#define SC2336_1L_DGAIN0_ADDR 0x3E06 +#define SC2336_1L_VMAX_ADDR 0x320E +#define SC2336_1L_TABLE_END 0xFFFF + +#define SC2336_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 SC2336_1L_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC2336_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 = SC2336_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_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; +#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); + SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC2336_1L_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC2336_1L_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC2336_1L_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC2336_1L_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_1L_FULL_LINES_MAX) ? SC2336_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_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_1L_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_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 */ + + /* 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_1L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC2336_1L_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_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC2336_1L_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC2336_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); + SC2336_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_aunSC2336_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 = sc2336_1L_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc2336_1L_addr_byte; + pstI2c_data[i].u32DataByteNum = sc2336_1L_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_1L_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC2336_1L_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC2336_1L_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC2336_1L_AGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC2336_1L_DGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC2336_1L_DGAIN0_ADDR + 1; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC2336_1L_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC2336_1L_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_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 (SC2336_1L_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC2336_1L_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_1L_MODE_S *pstMode = CVI_NULL; + + SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC2336_1L_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC2336_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; + + SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc2336_1L_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC2336_1L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC2336_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 = &sc2336_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 = sc2336_1L_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc2336_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 sc2336_1L_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC2336_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; + + SC2336_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)); + + SC2336_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; + + SC2336_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC2336_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 = SC2336_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, SC2336_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, SC2336_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, SC2336_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_au16SC2336_1L_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC2336_1L_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC2336_1L_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc2336_1L_standby, + .pfnRestart = sc2336_1L_restart, + .pfnMirrorFlip = sc2336_1L_mirror_flip, + .pfnWriteReg = sc2336_1L_write_register, + .pfnReadReg = sc2336_1L_read_register, + .pfnSetBusInfo = sc2336_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 = sc2336_1L_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_1L/sc2336_1L_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_1L/sc2336_1L_cmos_ex.h new file mode 100644 index 00000000..57e90cb1 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_1L/sc2336_1L_cmos_ex.h @@ -0,0 +1,85 @@ +#ifndef __SC2336_1L_CMOS_EX_H_ +#define __SC2336_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 sc2336_1L_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_1L_MODE_E { + SC2336_1L_MODE_1080P30 = 0, + SC2336_1L_MODE_LINEAR_NUM, + SC2336_1L_MODE_NUM +} SC2336_1L_MODE_E; + +typedef struct _SC2336_1L_STATE_S { + CVI_U32 u32Sexp_MAX; /* (2*{16’h3e23,16’h3e24} – 'd10)/2 */ +} SC2336_1L_STATE_S; + +typedef struct _SC2336_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_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16SexpMaxReg; /* {16’h3e23,16’h3e24} */ + char name[64]; +} SC2336_1L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC2336_1L[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC2336_1L_BusInfo[]; +extern CVI_U16 g_au16SC2336_1L_GainMode[]; +extern CVI_U16 g_au16SC2336_1L_L2SMode[]; +extern const CVI_U8 sc2336_1L_i2c_addr; +extern const CVI_U32 sc2336_1L_addr_byte; +extern const CVI_U32 sc2336_1L_data_byte; +extern void sc2336_1L_init(VI_PIPE ViPipe); +extern void sc2336_1L_exit(VI_PIPE ViPipe); +extern void sc2336_1L_standby(VI_PIPE ViPipe); +extern void sc2336_1L_restart(VI_PIPE ViPipe); +extern int sc2336_1L_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc2336_1L_read_register(VI_PIPE ViPipe, int addr); +extern void sc2336_1L_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc2336_1L_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC2336_1L_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_1L/sc2336_1L_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_1L/sc2336_1L_cmos_param.h new file mode 100644 index 00000000..5c6ca087 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_1L/sc2336_1L_cmos_param.h @@ -0,0 +1,125 @@ +#ifndef __SC2336_1L_CMOS_PARAM_H_ +#define __SC2336_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 "sc2336_1L_cmos_ex.h" + +static const SC2336_1L_MODE_S g_astSC2336_1L_mode[SC2336_1L_MODE_NUM] = { + [SC2336_1L_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_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, + .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_1L_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_1L/sc2336_1L_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_1L/sc2336_1L_sensor_ctl.c new file mode 100644 index 00000000..1137c840 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_1L/sc2336_1L_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 "sc2336_1L_cmos_ex.h" + +static void sc2336_1L_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc2336_1L_i2c_addr = 0x30; /* I2C Address of SC2336_1L */ +const CVI_U32 sc2336_1L_addr_byte = 2; +const CVI_U32 sc2336_1L_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc2336_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_aunSC2336_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, sc2336_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 sc2336_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 sc2336_1L_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_1L_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc2336_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, sc2336_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 (sc2336_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 sc2336_1L_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_1L_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc2336_1L_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc2336_1L_addr_byte + sc2336_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 sc2336_1L_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_1L_write_register(ViPipe, addr, data); + } +} + +void sc2336_1L_standby(VI_PIPE ViPipe) +{ + sc2336_1L_write_register(ViPipe, 0x0100, 0x00); +} + +void sc2336_1L_restart(VI_PIPE ViPipe) +{ + sc2336_1L_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc2336_1L_write_register(ViPipe, 0x0100, 0x01); +} + +void sc2336_1L_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC2336_1L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc2336_1L_write_register(ViPipe, + g_pastSC2336_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC2336_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define SC2336_1L_CHIP_ID_HI_ADDR 0x3107 +#define SC2336_1L_CHIP_ID_LO_ADDR 0x3108 +#define SC2336_1L_CHIP_ID 0xcb3a + +void sc2336_1L_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_1L_write_register(ViPipe, 0x3221, val); +} + +int sc2336_1L_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc2336_1L_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc2336_1L_read_register(ViPipe, SC2336_1L_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_1L_read_register(ViPipe, SC2336_1L_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_1L_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + + +void sc2336_1L_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + + bInit = g_pastSC2336_1L[ViPipe]->bInit; + enWDRMode = g_pastSC2336_1L[ViPipe]->enWDRMode; + + sc2336_1L_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_NONE) { + sc2336_1L_linear_1080p30_init(ViPipe); + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_NONE) { + sc2336_1L_linear_1080p30_init(ViPipe); + } + } + g_pastSC2336_1L[ViPipe]->bInit = CVI_TRUE; +} + +void sc2336_1L_exit(VI_PIPE ViPipe) +{ + sc2336_1L_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void sc2336_1L_linear_1080p30_init(VI_PIPE ViPipe) +{ + sc2336_1L_write_register(ViPipe, 0x0103, 0x01); + sc2336_1L_write_register(ViPipe, 0x0100, 0x00); + sc2336_1L_write_register(ViPipe, 0x36e9, 0x80); + sc2336_1L_write_register(ViPipe, 0x37f9, 0x80); + sc2336_1L_write_register(ViPipe, 0x3018, 0x12); + sc2336_1L_write_register(ViPipe, 0x3019, 0x0e); + sc2336_1L_write_register(ViPipe, 0x301f, 0x3b); + sc2336_1L_write_register(ViPipe, 0x3106, 0x05); + sc2336_1L_write_register(ViPipe, 0x3248, 0x04); + sc2336_1L_write_register(ViPipe, 0x3249, 0x0b); + sc2336_1L_write_register(ViPipe, 0x3253, 0x08); + sc2336_1L_write_register(ViPipe, 0x3301, 0x09); + sc2336_1L_write_register(ViPipe, 0x3302, 0xff); + sc2336_1L_write_register(ViPipe, 0x3303, 0x10); + sc2336_1L_write_register(ViPipe, 0x3306, 0x60); + sc2336_1L_write_register(ViPipe, 0x3307, 0x02); + sc2336_1L_write_register(ViPipe, 0x330a, 0x01); + sc2336_1L_write_register(ViPipe, 0x330b, 0x10); + sc2336_1L_write_register(ViPipe, 0x330c, 0x16); + sc2336_1L_write_register(ViPipe, 0x330d, 0xff); + sc2336_1L_write_register(ViPipe, 0x3318, 0x02); + sc2336_1L_write_register(ViPipe, 0x3321, 0x0a); + sc2336_1L_write_register(ViPipe, 0x3327, 0x0e); + sc2336_1L_write_register(ViPipe, 0x332b, 0x12); + sc2336_1L_write_register(ViPipe, 0x3333, 0x10); + sc2336_1L_write_register(ViPipe, 0x3334, 0x40); + sc2336_1L_write_register(ViPipe, 0x335e, 0x06); + sc2336_1L_write_register(ViPipe, 0x335f, 0x0a); + sc2336_1L_write_register(ViPipe, 0x3364, 0x1f); + sc2336_1L_write_register(ViPipe, 0x337c, 0x02); + sc2336_1L_write_register(ViPipe, 0x337d, 0x0e); + sc2336_1L_write_register(ViPipe, 0x3390, 0x09); + sc2336_1L_write_register(ViPipe, 0x3391, 0x0f); + sc2336_1L_write_register(ViPipe, 0x3392, 0x1f); + sc2336_1L_write_register(ViPipe, 0x3393, 0x20); + sc2336_1L_write_register(ViPipe, 0x3394, 0x20); + sc2336_1L_write_register(ViPipe, 0x3395, 0xff); + sc2336_1L_write_register(ViPipe, 0x33a2, 0x04); + sc2336_1L_write_register(ViPipe, 0x33b1, 0x80); + sc2336_1L_write_register(ViPipe, 0x33b2, 0x68); + sc2336_1L_write_register(ViPipe, 0x33b3, 0x42); + sc2336_1L_write_register(ViPipe, 0x33f9, 0x70); + sc2336_1L_write_register(ViPipe, 0x33fb, 0xd0); + sc2336_1L_write_register(ViPipe, 0x33fc, 0x0f); + sc2336_1L_write_register(ViPipe, 0x33fd, 0x1f); + sc2336_1L_write_register(ViPipe, 0x349f, 0x03); + sc2336_1L_write_register(ViPipe, 0x34a6, 0x0f); + sc2336_1L_write_register(ViPipe, 0x34a7, 0x1f); + sc2336_1L_write_register(ViPipe, 0x34a8, 0x42); + sc2336_1L_write_register(ViPipe, 0x34a9, 0x06); + sc2336_1L_write_register(ViPipe, 0x34aa, 0x01); + sc2336_1L_write_register(ViPipe, 0x34ab, 0x23); + sc2336_1L_write_register(ViPipe, 0x34ac, 0x01); + sc2336_1L_write_register(ViPipe, 0x34ad, 0x84); + sc2336_1L_write_register(ViPipe, 0x3630, 0xf4); + sc2336_1L_write_register(ViPipe, 0x3633, 0x22); + sc2336_1L_write_register(ViPipe, 0x3639, 0xf4); + sc2336_1L_write_register(ViPipe, 0x363c, 0x47); + sc2336_1L_write_register(ViPipe, 0x3670, 0x09); + sc2336_1L_write_register(ViPipe, 0x3674, 0xf4); + sc2336_1L_write_register(ViPipe, 0x3675, 0xfb); + sc2336_1L_write_register(ViPipe, 0x3676, 0xed); + sc2336_1L_write_register(ViPipe, 0x367c, 0x09); + sc2336_1L_write_register(ViPipe, 0x367d, 0x0f); + sc2336_1L_write_register(ViPipe, 0x3690, 0x33); + sc2336_1L_write_register(ViPipe, 0x3691, 0x33); + sc2336_1L_write_register(ViPipe, 0x3692, 0x43); + sc2336_1L_write_register(ViPipe, 0x3698, 0x89); + sc2336_1L_write_register(ViPipe, 0x3699, 0x96); + sc2336_1L_write_register(ViPipe, 0x369a, 0xd0); + sc2336_1L_write_register(ViPipe, 0x369b, 0xd0); + sc2336_1L_write_register(ViPipe, 0x369c, 0x09); + sc2336_1L_write_register(ViPipe, 0x369d, 0x0f); + sc2336_1L_write_register(ViPipe, 0x36a2, 0x09); + sc2336_1L_write_register(ViPipe, 0x36a3, 0x0f); + sc2336_1L_write_register(ViPipe, 0x36a4, 0x1f); + sc2336_1L_write_register(ViPipe, 0x36d0, 0x01); + sc2336_1L_write_register(ViPipe, 0x36ec, 0x0c); + sc2336_1L_write_register(ViPipe, 0x3722, 0xe1); + sc2336_1L_write_register(ViPipe, 0x3724, 0x41); + sc2336_1L_write_register(ViPipe, 0x3725, 0xc1); + sc2336_1L_write_register(ViPipe, 0x3728, 0x20); + sc2336_1L_write_register(ViPipe, 0x3900, 0x0d); + sc2336_1L_write_register(ViPipe, 0x3905, 0x98); + sc2336_1L_write_register(ViPipe, 0x391b, 0x81); + sc2336_1L_write_register(ViPipe, 0x391c, 0x10); + sc2336_1L_write_register(ViPipe, 0x3933, 0x81); + sc2336_1L_write_register(ViPipe, 0x3934, 0xc5); + sc2336_1L_write_register(ViPipe, 0x3940, 0x68); + sc2336_1L_write_register(ViPipe, 0x3941, 0x00); + sc2336_1L_write_register(ViPipe, 0x3942, 0x01); + sc2336_1L_write_register(ViPipe, 0x3943, 0xc6); + sc2336_1L_write_register(ViPipe, 0x3952, 0x02); + sc2336_1L_write_register(ViPipe, 0x3953, 0x0f); + sc2336_1L_write_register(ViPipe, 0x3e01, 0x45); + sc2336_1L_write_register(ViPipe, 0x3e02, 0xf0); + sc2336_1L_write_register(ViPipe, 0x3e08, 0x1f); + sc2336_1L_write_register(ViPipe, 0x3e1b, 0x14); + sc2336_1L_write_register(ViPipe, 0x440e, 0x02); + sc2336_1L_write_register(ViPipe, 0x4509, 0x38); + sc2336_1L_write_register(ViPipe, 0x4819, 0x09); + sc2336_1L_write_register(ViPipe, 0x481b, 0x05); + sc2336_1L_write_register(ViPipe, 0x481d, 0x14); + sc2336_1L_write_register(ViPipe, 0x481f, 0x04); + sc2336_1L_write_register(ViPipe, 0x4821, 0x0a); + sc2336_1L_write_register(ViPipe, 0x4823, 0x05); + sc2336_1L_write_register(ViPipe, 0x4825, 0x04); + sc2336_1L_write_register(ViPipe, 0x4827, 0x05); + sc2336_1L_write_register(ViPipe, 0x4829, 0x08); + sc2336_1L_write_register(ViPipe, 0x5799, 0x06); + sc2336_1L_write_register(ViPipe, 0x5ae0, 0xfe); + sc2336_1L_write_register(ViPipe, 0x5ae1, 0x40); + sc2336_1L_write_register(ViPipe, 0x5ae2, 0x30); + sc2336_1L_write_register(ViPipe, 0x5ae3, 0x28); + sc2336_1L_write_register(ViPipe, 0x5ae4, 0x20); + sc2336_1L_write_register(ViPipe, 0x5ae5, 0x30); + sc2336_1L_write_register(ViPipe, 0x5ae6, 0x28); + sc2336_1L_write_register(ViPipe, 0x5ae7, 0x20); + sc2336_1L_write_register(ViPipe, 0x5ae8, 0x3c); + sc2336_1L_write_register(ViPipe, 0x5ae9, 0x30); + sc2336_1L_write_register(ViPipe, 0x5aea, 0x28); + sc2336_1L_write_register(ViPipe, 0x5aeb, 0x3c); + sc2336_1L_write_register(ViPipe, 0x5aec, 0x30); + sc2336_1L_write_register(ViPipe, 0x5aed, 0x28); + sc2336_1L_write_register(ViPipe, 0x5aee, 0xfe); + sc2336_1L_write_register(ViPipe, 0x5aef, 0x40); + sc2336_1L_write_register(ViPipe, 0x5af4, 0x30); + sc2336_1L_write_register(ViPipe, 0x5af5, 0x28); + sc2336_1L_write_register(ViPipe, 0x5af6, 0x20); + sc2336_1L_write_register(ViPipe, 0x5af7, 0x30); + sc2336_1L_write_register(ViPipe, 0x5af8, 0x28); + sc2336_1L_write_register(ViPipe, 0x5af9, 0x20); + sc2336_1L_write_register(ViPipe, 0x5afa, 0x3c); + sc2336_1L_write_register(ViPipe, 0x5afb, 0x30); + sc2336_1L_write_register(ViPipe, 0x5afc, 0x28); + sc2336_1L_write_register(ViPipe, 0x5afd, 0x3c); + sc2336_1L_write_register(ViPipe, 0x5afe, 0x30); + sc2336_1L_write_register(ViPipe, 0x5aff, 0x28); + sc2336_1L_write_register(ViPipe, 0x36e9, 0x20); + sc2336_1L_write_register(ViPipe, 0x37f9, 0x27); + + sc2336_1L_default_reg_init(ViPipe); + + sc2336_1L_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC2336_1L 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave/Makefile new file mode 100644 index 00000000..c67e69f5 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_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_sc2336_slave.a +TARGET_SO = $(MW_LIB)/libsns_sc2336_slave.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave/sc2336_slave_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave/sc2336_slave_cmos.c new file mode 100644 index 00000000..95e1e254 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave/sc2336_slave_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_slave_cmos_ex.h" +#include "sc2336_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 SC2336_SLAVE_ID 35 +#define SENSOR_SC2336_SLAVE_WIDTH 1920 +#define SENSOR_SC2336_SLAVE_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC2336_Slave[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC2336_SLAVE_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC2336_Slave[dev]) +#define SC2336_SLAVE_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC2336_Slave[dev] = pstCtx) +#define SC2336_SLAVE_SENSOR_RESET_CTX(dev) (g_pastSC2336_Slave[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC2336_Slave_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC2336_Slave_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC2336_Slave_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +SC2336_SLAVE_STATE_S g_astSC2336_Slave_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_SLAVE Lines Range*****/ +#define SC2336_SLAVE_FULL_LINES_MAX (0xFFFF) + +/*****SC2336_SLAVE Register Address*****/ +#define SC2336_SLAVE_SHS1_0_ADDR 0x3E00 +#define SC2336_SLAVE_SHS1_1_ADDR 0x3E01 +#define SC2336_SLAVE_SHS1_2_ADDR 0x3E02 +#define SC2336_SLAVE_AGAIN0_ADDR 0x3E09 +#define SC2336_SLAVE_DGAIN0_ADDR 0x3E06 +#define SC2336_SLAVE_VMAX_ADDR 0x320E +#define SC2336_SLAVE_TABLE_END 0xFFFF + +#define SC2336_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 SC2336_SLAVE_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC2336_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC2336_Slave_mode[pstSnsState->u8ImgMode]; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC2336_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_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_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC2336_Slave_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC2336_Slave_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC2336_Slave_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC2336_SLAVE_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_SLAVE_FULL_LINES_MAX) ? SC2336_SLAVE_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_SLAVE_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_SLAVE_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_SLAVE_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2336_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC2336_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; + + SC2336_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC2336_SLAVE_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC2336_Slave_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_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_aunSC2336_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 = sc2336_slave_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc2336_slave_addr_byte; + pstI2c_data[i].u32DataByteNum = sc2336_slave_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_SLAVE_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC2336_SLAVE_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC2336_SLAVE_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC2336_SLAVE_AGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC2336_SLAVE_DGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC2336_SLAVE_DGAIN0_ADDR + 1; + // pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC2336_SLAVE_VMAX_ADDR; + // pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC2336_SLAVE_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_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 (SC2336_SLAVE_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC2336_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 { + 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_SLAVE_MODE_S *pstMode = CVI_NULL; + + SC2336_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC2336_SLAVE_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC2336_Slave_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_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc2336_slave_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC2336_Slave_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC2336_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 = &sc2336_slave_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_slave_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc2336_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 sc2336_slave_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC2336_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; + + SC2336_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)); + + SC2336_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; + + SC2336_SLAVE_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC2336_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 = SC2336_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, SC2336_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, SC2336_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, SC2336_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_au16SC2336_Slave_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC2336_Slave_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC2336_Slave_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc2336_slave_standby, + .pfnRestart = sc2336_slave_restart, + .pfnMirrorFlip = sc2336_slave_mirror_flip, + .pfnWriteReg = sc2336_slave_write_register, + .pfnReadReg = sc2336_slave_read_register, + .pfnSetBusInfo = sc2336_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 = sc2336_slave_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave/sc2336_slave_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave/sc2336_slave_cmos_ex.h new file mode 100644 index 00000000..979dc10a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave/sc2336_slave_cmos_ex.h @@ -0,0 +1,85 @@ +#ifndef __SC2336_SLAVE_CMOS_EX_H_ +#define __SC2336_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 sc2336_slave_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_SLAVE_MODE_E { + SC2336_SLAVE_MODE_1080P30 = 0, + SC2336_SLAVE_MODE_LINEAR_NUM, + SC2336_SLAVE_MODE_NUM +} SC2336_SLAVE_MODE_E; + +typedef struct _SC2336_SLAVE_STATE_S { + CVI_U32 u32Sexp_MAX; +} SC2336_SLAVE_STATE_S; + +typedef struct _SC2336_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 u16SexpMaxReg; + char name[64]; +} SC2336_SLAVE_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC2336_Slave[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC2336_Slave_BusInfo[]; +extern CVI_U16 g_au16SC2336_Slave_GainMode[]; +extern CVI_U16 g_au16SC2336_Slave_L2SMode[]; +extern const CVI_U8 sc2336_slave_i2c_addr; +extern const CVI_U32 sc2336_slave_addr_byte; +extern const CVI_U32 sc2336_slave_data_byte; +extern void sc2336_slave_init(VI_PIPE ViPipe); +extern void sc2336_slave_exit(VI_PIPE ViPipe); +extern void sc2336_slave_standby(VI_PIPE ViPipe); +extern void sc2336_slave_restart(VI_PIPE ViPipe); +extern int sc2336_slave_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc2336_slave_read_register(VI_PIPE ViPipe, int addr); +extern void sc2336_slave_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc2336_slave_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC2336_SLAVE_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave/sc2336_slave_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave/sc2336_slave_cmos_param.h new file mode 100644 index 00000000..d2114b13 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave/sc2336_slave_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_slave_cmos_ex.h" + +static const SC2336_SLAVE_MODE_S g_astSC2336_Slave_mode[SC2336_SLAVE_MODE_NUM] = { + [SC2336_SLAVE_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_slave_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_SLAVE_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave/sc2336_slave_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave/sc2336_slave_sensor_ctl.c new file mode 100644 index 00000000..a1d6eb5a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave/sc2336_slave_sensor_ctl.c @@ -0,0 +1,436 @@ +#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_slave_cmos_ex.h" + +static void sc2336_slave_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc2336_slave_i2c_addr = 0x30; /* I2C Address of SC2336 */ +const CVI_U32 sc2336_slave_addr_byte = 2; +const CVI_U32 sc2336_slave_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc2336_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_aunSC2336_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/cvi_i2c_drv-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc2336_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 sc2336_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 sc2336_slave_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_slave_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc2336_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, sc2336_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 (sc2336_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 sc2336_slave_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_slave_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc2336_slave_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc2336_slave_addr_byte + sc2336_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 sc2336_slave_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_slave_write_register(ViPipe, addr, data); + } +} + +void sc2336_slave_standby(VI_PIPE ViPipe) +{ + sc2336_slave_write_register(ViPipe, 0x0100, 0x00); +} + +void sc2336_slave_restart(VI_PIPE ViPipe) +{ + sc2336_slave_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc2336_slave_write_register(ViPipe, 0x0100, 0x01); +} + +void sc2336_slave_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC2336_Slave[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc2336_slave_write_register(ViPipe, + g_pastSC2336_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC2336_Slave[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_slave_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_slave_write_register(ViPipe, 0x3221, val); +} + +int sc2336_slave_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc2336_slave_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc2336_slave_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_slave_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_slave_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + + bInit = g_pastSC2336_Slave[ViPipe]->bInit; + enWDRMode = g_pastSC2336_Slave[ViPipe]->enWDRMode; + + sc2336_slave_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_NONE) { + sc2336_slave_linear_1080p30_init(ViPipe); + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_NONE) { + sc2336_slave_linear_1080p30_init(ViPipe); + } + } + g_pastSC2336_Slave[ViPipe]->bInit = CVI_TRUE; +} + +void sc2336_slave_exit(VI_PIPE ViPipe) +{ + sc2336_slave_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void sc2336_slave_linear_1080p30_init(VI_PIPE ViPipe) +{ + sc2336_slave_write_register(ViPipe, 0x0103, 0x01); + sc2336_slave_write_register(ViPipe, 0x0100, 0x00); + sc2336_slave_write_register(ViPipe, 0x36e9, 0x80); + sc2336_slave_write_register(ViPipe, 0x37f9, 0x80); + sc2336_slave_write_register(ViPipe, 0x300a, 0x20); + sc2336_slave_write_register(ViPipe, 0x301f, 0xa8); + sc2336_slave_write_register(ViPipe, 0x3106, 0x05); + sc2336_slave_write_register(ViPipe, 0x320c, 0x08); + sc2336_slave_write_register(ViPipe, 0x320d, 0x4a); + sc2336_slave_write_register(ViPipe, 0x320e, 0x04); + sc2336_slave_write_register(ViPipe, 0x320f, 0x6b); + sc2336_slave_write_register(ViPipe, 0x3222, 0x02); + sc2336_slave_write_register(ViPipe, 0x3224, 0x82); + sc2336_slave_write_register(ViPipe, 0x322e, 0x04); + sc2336_slave_write_register(ViPipe, 0x322f, 0x67); + sc2336_slave_write_register(ViPipe, 0x3248, 0x04); + sc2336_slave_write_register(ViPipe, 0x3249, 0x0b); + sc2336_slave_write_register(ViPipe, 0x3253, 0x08); + sc2336_slave_write_register(ViPipe, 0x3301, 0x09); + sc2336_slave_write_register(ViPipe, 0x3302, 0xff); + sc2336_slave_write_register(ViPipe, 0x3303, 0x10); + sc2336_slave_write_register(ViPipe, 0x3306, 0x60); + sc2336_slave_write_register(ViPipe, 0x3307, 0x02); + sc2336_slave_write_register(ViPipe, 0x330a, 0x01); + sc2336_slave_write_register(ViPipe, 0x330b, 0x10); + sc2336_slave_write_register(ViPipe, 0x330c, 0x16); + sc2336_slave_write_register(ViPipe, 0x330d, 0xff); + sc2336_slave_write_register(ViPipe, 0x3318, 0x02); + sc2336_slave_write_register(ViPipe, 0x3321, 0x0a); + sc2336_slave_write_register(ViPipe, 0x3327, 0x0e); + sc2336_slave_write_register(ViPipe, 0x332b, 0x12); + sc2336_slave_write_register(ViPipe, 0x3333, 0x10); + sc2336_slave_write_register(ViPipe, 0x3334, 0x40); + sc2336_slave_write_register(ViPipe, 0x335e, 0x06); + sc2336_slave_write_register(ViPipe, 0x335f, 0x0a); + sc2336_slave_write_register(ViPipe, 0x3364, 0x1f); + sc2336_slave_write_register(ViPipe, 0x337c, 0x02); + sc2336_slave_write_register(ViPipe, 0x337d, 0x0e); + sc2336_slave_write_register(ViPipe, 0x3390, 0x09); + sc2336_slave_write_register(ViPipe, 0x3391, 0x0f); + sc2336_slave_write_register(ViPipe, 0x3392, 0x1f); + sc2336_slave_write_register(ViPipe, 0x3393, 0x20); + sc2336_slave_write_register(ViPipe, 0x3394, 0x20); + sc2336_slave_write_register(ViPipe, 0x3395, 0xff); + sc2336_slave_write_register(ViPipe, 0x33a2, 0x04); + sc2336_slave_write_register(ViPipe, 0x33b1, 0x80); + sc2336_slave_write_register(ViPipe, 0x33b2, 0x68); + sc2336_slave_write_register(ViPipe, 0x33b3, 0x42); + sc2336_slave_write_register(ViPipe, 0x33f9, 0x78); + sc2336_slave_write_register(ViPipe, 0x33fb, 0xd8); + sc2336_slave_write_register(ViPipe, 0x33fc, 0x0f); + sc2336_slave_write_register(ViPipe, 0x33fd, 0x1f); + sc2336_slave_write_register(ViPipe, 0x349f, 0x03); + sc2336_slave_write_register(ViPipe, 0x34a6, 0x0f); + sc2336_slave_write_register(ViPipe, 0x34a7, 0x1f); + sc2336_slave_write_register(ViPipe, 0x34a8, 0x42); + sc2336_slave_write_register(ViPipe, 0x34a9, 0x06); + sc2336_slave_write_register(ViPipe, 0x34aa, 0x01); + sc2336_slave_write_register(ViPipe, 0x34ab, 0x28); + sc2336_slave_write_register(ViPipe, 0x34ac, 0x01); + sc2336_slave_write_register(ViPipe, 0x34ad, 0x90); + sc2336_slave_write_register(ViPipe, 0x3630, 0xf4); + sc2336_slave_write_register(ViPipe, 0x3633, 0x22); + sc2336_slave_write_register(ViPipe, 0x3639, 0xf4); + sc2336_slave_write_register(ViPipe, 0x363c, 0x47); + sc2336_slave_write_register(ViPipe, 0x3650, 0x33); + sc2336_slave_write_register(ViPipe, 0x3670, 0x09); + sc2336_slave_write_register(ViPipe, 0x3674, 0xf4); + sc2336_slave_write_register(ViPipe, 0x3675, 0xfb); + sc2336_slave_write_register(ViPipe, 0x3676, 0xed); + sc2336_slave_write_register(ViPipe, 0x367c, 0x09); + sc2336_slave_write_register(ViPipe, 0x367d, 0x0f); + sc2336_slave_write_register(ViPipe, 0x3690, 0x22); + sc2336_slave_write_register(ViPipe, 0x3691, 0x22); + sc2336_slave_write_register(ViPipe, 0x3692, 0x22); + sc2336_slave_write_register(ViPipe, 0x3698, 0x89); + sc2336_slave_write_register(ViPipe, 0x3699, 0x96); + sc2336_slave_write_register(ViPipe, 0x369a, 0xd0); + sc2336_slave_write_register(ViPipe, 0x369b, 0xd0); + sc2336_slave_write_register(ViPipe, 0x369c, 0x09); + sc2336_slave_write_register(ViPipe, 0x369d, 0x0f); + sc2336_slave_write_register(ViPipe, 0x36a2, 0x09); + sc2336_slave_write_register(ViPipe, 0x36a3, 0x0f); + sc2336_slave_write_register(ViPipe, 0x36a4, 0x1f); + sc2336_slave_write_register(ViPipe, 0x36d0, 0x01); + sc2336_slave_write_register(ViPipe, 0x36ea, 0x08); + sc2336_slave_write_register(ViPipe, 0x36eb, 0x0c); + sc2336_slave_write_register(ViPipe, 0x36ec, 0x1c); + sc2336_slave_write_register(ViPipe, 0x36ed, 0x28); + sc2336_slave_write_register(ViPipe, 0x3722, 0xe1); + sc2336_slave_write_register(ViPipe, 0x3724, 0x41); + sc2336_slave_write_register(ViPipe, 0x3725, 0xc1); + sc2336_slave_write_register(ViPipe, 0x3728, 0x20); + sc2336_slave_write_register(ViPipe, 0x37fa, 0x08); + sc2336_slave_write_register(ViPipe, 0x37fb, 0x32); + sc2336_slave_write_register(ViPipe, 0x37fc, 0x11); + sc2336_slave_write_register(ViPipe, 0x37fd, 0x37); + sc2336_slave_write_register(ViPipe, 0x3900, 0x0d); + sc2336_slave_write_register(ViPipe, 0x3905, 0x98); + sc2336_slave_write_register(ViPipe, 0x391b, 0x81); + sc2336_slave_write_register(ViPipe, 0x391c, 0x10); + sc2336_slave_write_register(ViPipe, 0x3933, 0x81); + sc2336_slave_write_register(ViPipe, 0x3934, 0xc5); + sc2336_slave_write_register(ViPipe, 0x3940, 0x68); + sc2336_slave_write_register(ViPipe, 0x3941, 0x00); + sc2336_slave_write_register(ViPipe, 0x3942, 0x01); + sc2336_slave_write_register(ViPipe, 0x3943, 0xc6); + sc2336_slave_write_register(ViPipe, 0x3952, 0x02); + sc2336_slave_write_register(ViPipe, 0x3953, 0x0f); + sc2336_slave_write_register(ViPipe, 0x3e01, 0x46); + sc2336_slave_write_register(ViPipe, 0x3e02, 0x50); + sc2336_slave_write_register(ViPipe, 0x3e08, 0x1f); + sc2336_slave_write_register(ViPipe, 0x3e1b, 0x14); + sc2336_slave_write_register(ViPipe, 0x440e, 0x02); + sc2336_slave_write_register(ViPipe, 0x4509, 0x38); + sc2336_slave_write_register(ViPipe, 0x4819, 0x05); + sc2336_slave_write_register(ViPipe, 0x481b, 0x03); + sc2336_slave_write_register(ViPipe, 0x481d, 0x0a); + sc2336_slave_write_register(ViPipe, 0x481f, 0x02); + sc2336_slave_write_register(ViPipe, 0x4821, 0x08); + sc2336_slave_write_register(ViPipe, 0x4823, 0x03); + sc2336_slave_write_register(ViPipe, 0x4825, 0x02); + sc2336_slave_write_register(ViPipe, 0x4827, 0x03); + sc2336_slave_write_register(ViPipe, 0x4829, 0x04); + sc2336_slave_write_register(ViPipe, 0x5799, 0x06); + sc2336_slave_write_register(ViPipe, 0x5ae0, 0xfe); + sc2336_slave_write_register(ViPipe, 0x5ae1, 0x40); + sc2336_slave_write_register(ViPipe, 0x5ae2, 0x30); + sc2336_slave_write_register(ViPipe, 0x5ae3, 0x28); + sc2336_slave_write_register(ViPipe, 0x5ae4, 0x20); + sc2336_slave_write_register(ViPipe, 0x5ae5, 0x30); + sc2336_slave_write_register(ViPipe, 0x5ae6, 0x28); + sc2336_slave_write_register(ViPipe, 0x5ae7, 0x20); + sc2336_slave_write_register(ViPipe, 0x5ae8, 0x3c); + sc2336_slave_write_register(ViPipe, 0x5ae9, 0x30); + sc2336_slave_write_register(ViPipe, 0x5aea, 0x28); + sc2336_slave_write_register(ViPipe, 0x5aeb, 0x3c); + sc2336_slave_write_register(ViPipe, 0x5aec, 0x30); + sc2336_slave_write_register(ViPipe, 0x5aed, 0x28); + sc2336_slave_write_register(ViPipe, 0x5aee, 0xfe); + sc2336_slave_write_register(ViPipe, 0x5aef, 0x40); + sc2336_slave_write_register(ViPipe, 0x5af4, 0x30); + sc2336_slave_write_register(ViPipe, 0x5af5, 0x28); + sc2336_slave_write_register(ViPipe, 0x5af6, 0x20); + sc2336_slave_write_register(ViPipe, 0x5af7, 0x30); + sc2336_slave_write_register(ViPipe, 0x5af8, 0x28); + sc2336_slave_write_register(ViPipe, 0x5af9, 0x20); + sc2336_slave_write_register(ViPipe, 0x5afa, 0x3c); + sc2336_slave_write_register(ViPipe, 0x5afb, 0x30); + sc2336_slave_write_register(ViPipe, 0x5afc, 0x28); + sc2336_slave_write_register(ViPipe, 0x5afd, 0x3c); + sc2336_slave_write_register(ViPipe, 0x5afe, 0x30); + sc2336_slave_write_register(ViPipe, 0x5aff, 0x28); + sc2336_slave_write_register(ViPipe, 0x36e9, 0x44); + sc2336_slave_write_register(ViPipe, 0x37f9, 0x44); + sc2336_slave_write_register(ViPipe, 0x0100, 0x01); + + //sc2336_slave_default_reg_init(ViPipe); + + sc2336_slave_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC2336 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave1/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave1/Makefile new file mode 100644 index 00000000..c67e69f5 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave1/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_slave.a +TARGET_SO = $(MW_LIB)/libsns_sc2336_slave.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave1/sc2336_slave1_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave1/sc2336_slave1_cmos.c new file mode 100644 index 00000000..9ac57f7a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave1/sc2336_slave1_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_slave1_cmos_ex.h" +#include "sc2336_slave1_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_SLAVE1_ID 35 +#define SENSOR_SC2336_SLAVE1_WIDTH 1920 +#define SENSOR_SC2336_SLAVE1_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC2336_Slave1[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC2336_SLAVE1_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC2336_Slave1[dev]) +#define SC2336_SLAVE1_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC2336_Slave1[dev] = pstCtx) +#define SC2336_SLAVE1_SENSOR_RESET_CTX(dev) (g_pastSC2336_Slave1[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC2336_Slave1_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC2336_Slave1_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC2336_Slave1_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +SC2336_SLAVE1_STATE_S g_astSC2336_Slave1_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_SLAVE Lines Range*****/ +#define SC2336_SLAVE1_FULL_LINES_MAX (0xFFFF) + +/*****SC2336_SLAVE Register Address*****/ +#define SC2336_SLAVE1_SHS1_0_ADDR 0x3E00 +#define SC2336_SLAVE1_SHS1_1_ADDR 0x3E01 +#define SC2336_SLAVE1_SHS1_2_ADDR 0x3E02 +#define SC2336_SLAVE1_AGAIN0_ADDR 0x3E09 +#define SC2336_SLAVE1_DGAIN0_ADDR 0x3E06 +#define SC2336_SLAVE1_VMAX_ADDR 0x320E +#define SC2336_SLAVE1_TABLE_END 0xFFFF + +#define SC2336_SLAVE1_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_SLAVE1_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC2336_SLAVE1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC2336_Slave_mode[pstSnsState->u8ImgMode]; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC2336_SLAVE1_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_SLAVE1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC2336_Slave_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC2336_Slave_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC2336_Slave_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC2336_SLAVE1_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_SLAVE1_FULL_LINES_MAX) ? SC2336_SLAVE1_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_SLAVE1_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_SLAVE1_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_SLAVE1_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2336_SLAVE1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC2336_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; + + SC2336_SLAVE1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC2336_SLAVE1_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC2336_Slave_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_SLAVE1_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_Slave1_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_slave1_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc2336_slave1_addr_byte; + pstI2c_data[i].u32DataByteNum = sc2336_slave1_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_SLAVE1_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC2336_SLAVE1_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC2336_SLAVE1_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC2336_SLAVE1_AGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC2336_SLAVE1_DGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC2336_SLAVE1_DGAIN0_ADDR + 1; + // pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC2336_SLAVE1_VMAX_ADDR; + // pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC2336_SLAVE1_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_SLAVE1_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_SLAVE1_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC2336_SLAVE1_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_SLAVE1_MODE_S *pstMode = CVI_NULL; + + SC2336_SLAVE1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC2336_SLAVE1_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC2336_Slave_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_SLAVE1_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc2336_slave1_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC2336_Slave_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC2336_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 = &sc2336_slave1_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_slave1_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc2336_slave1_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_slave1_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC2336_Slave1_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_SLAVE1_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_SLAVE1_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_SLAVE1_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC2336_SLAVE1_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_SLAVE1_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_SLAVE1_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_SLAVE1_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_SLAVE1_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_Slave1_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC2336_Slave1_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC2336_Slave1_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc2336_slave1_standby, + .pfnRestart = sc2336_slave1_restart, + .pfnMirrorFlip = sc2336_slave1_mirror_flip, + .pfnWriteReg = sc2336_slave1_write_register, + .pfnReadReg = sc2336_slave1_read_register, + .pfnSetBusInfo = sc2336_slave1_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_slave1_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave1/sc2336_slave1_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave1/sc2336_slave1_cmos_ex.h new file mode 100644 index 00000000..76e5aae5 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave1/sc2336_slave1_cmos_ex.h @@ -0,0 +1,85 @@ +#ifndef __SC2336_SLAVE1_CMOS_EX_H_ +#define __SC2336_SLAVE1_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_slave_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_SLAVE1_MODE_E { + SC2336_SLAVE1_MODE_1080P30 = 0, + SC2336_SLAVE1_MODE_LINEAR_NUM, + SC2336_SLAVE1_MODE_NUM +} SC2336_SLAVE1_MODE_E; + +typedef struct _SC2336_SLAVE1_STATE_S { + CVI_U32 u32Sexp_MAX; +} SC2336_SLAVE1_STATE_S; + +typedef struct _SC2336_SLAVE1_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_SLAVE1_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC2336_Slave1[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC2336_Slave1_BusInfo[]; +extern CVI_U16 g_au16SC2336_Slave1_GainMode[]; +extern CVI_U16 g_au16SC2336_Slave1_L2SMode[]; +extern const CVI_U8 sc2336_slave1_i2c_addr; +extern const CVI_U32 sc2336_slave1_addr_byte; +extern const CVI_U32 sc2336_slave1_data_byte; +extern void sc2336_slave1_init(VI_PIPE ViPipe); +extern void sc2336_slave1_exit(VI_PIPE ViPipe); +extern void sc2336_slave1_standby(VI_PIPE ViPipe); +extern void sc2336_slave1_restart(VI_PIPE ViPipe); +extern int sc2336_slave1_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc2336_slave1_read_register(VI_PIPE ViPipe, int addr); +extern void sc2336_slave1_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc2336_slave1_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC2336_SLAVE1_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave1/sc2336_slave1_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave1/sc2336_slave1_cmos_param.h new file mode 100644 index 00000000..8f0f3eb4 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave1/sc2336_slave1_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_slave1_cmos_ex.h" + +static const SC2336_SLAVE1_MODE_S g_astSC2336_Slave_mode[SC2336_SLAVE1_MODE_NUM] = { + [SC2336_SLAVE1_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_slave1_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_SLAVE1_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave1/sc2336_slave1_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave1/sc2336_slave1_sensor_ctl.c new file mode 100644 index 00000000..db7824c9 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336_slave1/sc2336_slave1_sensor_ctl.c @@ -0,0 +1,436 @@ +#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_slave1_cmos_ex.h" + +static void sc2336_slave1_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc2336_slave1_i2c_addr = 0x30; /* I2C Address of SC2336 */ +const CVI_U32 sc2336_slave1_addr_byte = 2; +const CVI_U32 sc2336_slave1_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc2336_slave1_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_Slave1_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_slave1_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_slave1_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_slave1_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_slave1_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc2336_slave1_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_slave1_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_slave1_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_slave1_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_slave1_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc2336_slave1_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc2336_slave1_addr_byte + sc2336_slave1_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_slave1_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_slave1_write_register(ViPipe, addr, data); + } +} + +void sc2336_slave1_standby(VI_PIPE ViPipe) +{ + sc2336_slave1_write_register(ViPipe, 0x0100, 0x00); +} + +void sc2336_slave1_restart(VI_PIPE ViPipe) +{ + sc2336_slave1_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc2336_slave1_write_register(ViPipe, 0x0100, 0x01); +} + +void sc2336_slave1_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC2336_Slave1[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc2336_slave1_write_register(ViPipe, + g_pastSC2336_Slave1[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC2336_Slave1[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_slave1_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_slave1_write_register(ViPipe, 0x3221, val); +} + +int sc2336_slave1_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc2336_slave1_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc2336_slave1_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_slave1_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_slave1_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + + bInit = g_pastSC2336_Slave1[ViPipe]->bInit; + enWDRMode = g_pastSC2336_Slave1[ViPipe]->enWDRMode; + + sc2336_slave1_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_NONE) { + sc2336_slave1_linear_1080p30_init(ViPipe); + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_NONE) { + sc2336_slave1_linear_1080p30_init(ViPipe); + } + } + g_pastSC2336_Slave1[ViPipe]->bInit = CVI_TRUE; +} + +void sc2336_slave1_exit(VI_PIPE ViPipe) +{ + sc2336_slave1_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void sc2336_slave1_linear_1080p30_init(VI_PIPE ViPipe) +{ + sc2336_slave1_write_register(ViPipe, 0x0103, 0x01); + sc2336_slave1_write_register(ViPipe, 0x0100, 0x00); + sc2336_slave1_write_register(ViPipe, 0x36e9, 0x80); + sc2336_slave1_write_register(ViPipe, 0x37f9, 0x80); + sc2336_slave1_write_register(ViPipe, 0x300a, 0x20); + sc2336_slave1_write_register(ViPipe, 0x301f, 0xa8); + sc2336_slave1_write_register(ViPipe, 0x3106, 0x05); + sc2336_slave1_write_register(ViPipe, 0x320c, 0x08); + sc2336_slave1_write_register(ViPipe, 0x320d, 0x4a); + sc2336_slave1_write_register(ViPipe, 0x320e, 0x04); + sc2336_slave1_write_register(ViPipe, 0x320f, 0x6b); + sc2336_slave1_write_register(ViPipe, 0x3222, 0x02); + sc2336_slave1_write_register(ViPipe, 0x3224, 0x82); + sc2336_slave1_write_register(ViPipe, 0x322e, 0x04); + sc2336_slave1_write_register(ViPipe, 0x322f, 0x67); + sc2336_slave1_write_register(ViPipe, 0x3248, 0x04); + sc2336_slave1_write_register(ViPipe, 0x3249, 0x0b); + sc2336_slave1_write_register(ViPipe, 0x3253, 0x08); + sc2336_slave1_write_register(ViPipe, 0x3301, 0x09); + sc2336_slave1_write_register(ViPipe, 0x3302, 0xff); + sc2336_slave1_write_register(ViPipe, 0x3303, 0x10); + sc2336_slave1_write_register(ViPipe, 0x3306, 0x60); + sc2336_slave1_write_register(ViPipe, 0x3307, 0x02); + sc2336_slave1_write_register(ViPipe, 0x330a, 0x01); + sc2336_slave1_write_register(ViPipe, 0x330b, 0x10); + sc2336_slave1_write_register(ViPipe, 0x330c, 0x16); + sc2336_slave1_write_register(ViPipe, 0x330d, 0xff); + sc2336_slave1_write_register(ViPipe, 0x3318, 0x02); + sc2336_slave1_write_register(ViPipe, 0x3321, 0x0a); + sc2336_slave1_write_register(ViPipe, 0x3327, 0x0e); + sc2336_slave1_write_register(ViPipe, 0x332b, 0x12); + sc2336_slave1_write_register(ViPipe, 0x3333, 0x10); + sc2336_slave1_write_register(ViPipe, 0x3334, 0x40); + sc2336_slave1_write_register(ViPipe, 0x335e, 0x06); + sc2336_slave1_write_register(ViPipe, 0x335f, 0x0a); + sc2336_slave1_write_register(ViPipe, 0x3364, 0x1f); + sc2336_slave1_write_register(ViPipe, 0x337c, 0x02); + sc2336_slave1_write_register(ViPipe, 0x337d, 0x0e); + sc2336_slave1_write_register(ViPipe, 0x3390, 0x09); + sc2336_slave1_write_register(ViPipe, 0x3391, 0x0f); + sc2336_slave1_write_register(ViPipe, 0x3392, 0x1f); + sc2336_slave1_write_register(ViPipe, 0x3393, 0x20); + sc2336_slave1_write_register(ViPipe, 0x3394, 0x20); + sc2336_slave1_write_register(ViPipe, 0x3395, 0xff); + sc2336_slave1_write_register(ViPipe, 0x33a2, 0x04); + sc2336_slave1_write_register(ViPipe, 0x33b1, 0x80); + sc2336_slave1_write_register(ViPipe, 0x33b2, 0x68); + sc2336_slave1_write_register(ViPipe, 0x33b3, 0x42); + sc2336_slave1_write_register(ViPipe, 0x33f9, 0x78); + sc2336_slave1_write_register(ViPipe, 0x33fb, 0xd8); + sc2336_slave1_write_register(ViPipe, 0x33fc, 0x0f); + sc2336_slave1_write_register(ViPipe, 0x33fd, 0x1f); + sc2336_slave1_write_register(ViPipe, 0x349f, 0x03); + sc2336_slave1_write_register(ViPipe, 0x34a6, 0x0f); + sc2336_slave1_write_register(ViPipe, 0x34a7, 0x1f); + sc2336_slave1_write_register(ViPipe, 0x34a8, 0x42); + sc2336_slave1_write_register(ViPipe, 0x34a9, 0x06); + sc2336_slave1_write_register(ViPipe, 0x34aa, 0x01); + sc2336_slave1_write_register(ViPipe, 0x34ab, 0x28); + sc2336_slave1_write_register(ViPipe, 0x34ac, 0x01); + sc2336_slave1_write_register(ViPipe, 0x34ad, 0x90); + sc2336_slave1_write_register(ViPipe, 0x3630, 0xf4); + sc2336_slave1_write_register(ViPipe, 0x3633, 0x22); + sc2336_slave1_write_register(ViPipe, 0x3639, 0xf4); + sc2336_slave1_write_register(ViPipe, 0x363c, 0x47); + sc2336_slave1_write_register(ViPipe, 0x3650, 0x33); + sc2336_slave1_write_register(ViPipe, 0x3670, 0x09); + sc2336_slave1_write_register(ViPipe, 0x3674, 0xf4); + sc2336_slave1_write_register(ViPipe, 0x3675, 0xfb); + sc2336_slave1_write_register(ViPipe, 0x3676, 0xed); + sc2336_slave1_write_register(ViPipe, 0x367c, 0x09); + sc2336_slave1_write_register(ViPipe, 0x367d, 0x0f); + sc2336_slave1_write_register(ViPipe, 0x3690, 0x22); + sc2336_slave1_write_register(ViPipe, 0x3691, 0x22); + sc2336_slave1_write_register(ViPipe, 0x3692, 0x22); + sc2336_slave1_write_register(ViPipe, 0x3698, 0x89); + sc2336_slave1_write_register(ViPipe, 0x3699, 0x96); + sc2336_slave1_write_register(ViPipe, 0x369a, 0xd0); + sc2336_slave1_write_register(ViPipe, 0x369b, 0xd0); + sc2336_slave1_write_register(ViPipe, 0x369c, 0x09); + sc2336_slave1_write_register(ViPipe, 0x369d, 0x0f); + sc2336_slave1_write_register(ViPipe, 0x36a2, 0x09); + sc2336_slave1_write_register(ViPipe, 0x36a3, 0x0f); + sc2336_slave1_write_register(ViPipe, 0x36a4, 0x1f); + sc2336_slave1_write_register(ViPipe, 0x36d0, 0x01); + sc2336_slave1_write_register(ViPipe, 0x36ea, 0x08); + sc2336_slave1_write_register(ViPipe, 0x36eb, 0x0c); + sc2336_slave1_write_register(ViPipe, 0x36ec, 0x1c); + sc2336_slave1_write_register(ViPipe, 0x36ed, 0x28); + sc2336_slave1_write_register(ViPipe, 0x3722, 0xe1); + sc2336_slave1_write_register(ViPipe, 0x3724, 0x41); + sc2336_slave1_write_register(ViPipe, 0x3725, 0xc1); + sc2336_slave1_write_register(ViPipe, 0x3728, 0x20); + sc2336_slave1_write_register(ViPipe, 0x37fa, 0x08); + sc2336_slave1_write_register(ViPipe, 0x37fb, 0x32); + sc2336_slave1_write_register(ViPipe, 0x37fc, 0x11); + sc2336_slave1_write_register(ViPipe, 0x37fd, 0x37); + sc2336_slave1_write_register(ViPipe, 0x3900, 0x0d); + sc2336_slave1_write_register(ViPipe, 0x3905, 0x98); + sc2336_slave1_write_register(ViPipe, 0x391b, 0x81); + sc2336_slave1_write_register(ViPipe, 0x391c, 0x10); + sc2336_slave1_write_register(ViPipe, 0x3933, 0x81); + sc2336_slave1_write_register(ViPipe, 0x3934, 0xc5); + sc2336_slave1_write_register(ViPipe, 0x3940, 0x68); + sc2336_slave1_write_register(ViPipe, 0x3941, 0x00); + sc2336_slave1_write_register(ViPipe, 0x3942, 0x01); + sc2336_slave1_write_register(ViPipe, 0x3943, 0xc6); + sc2336_slave1_write_register(ViPipe, 0x3952, 0x02); + sc2336_slave1_write_register(ViPipe, 0x3953, 0x0f); + sc2336_slave1_write_register(ViPipe, 0x3e01, 0x46); + sc2336_slave1_write_register(ViPipe, 0x3e02, 0x50); + sc2336_slave1_write_register(ViPipe, 0x3e08, 0x1f); + sc2336_slave1_write_register(ViPipe, 0x3e1b, 0x14); + sc2336_slave1_write_register(ViPipe, 0x440e, 0x02); + sc2336_slave1_write_register(ViPipe, 0x4509, 0x38); + sc2336_slave1_write_register(ViPipe, 0x4819, 0x05); + sc2336_slave1_write_register(ViPipe, 0x481b, 0x03); + sc2336_slave1_write_register(ViPipe, 0x481d, 0x0a); + sc2336_slave1_write_register(ViPipe, 0x481f, 0x02); + sc2336_slave1_write_register(ViPipe, 0x4821, 0x08); + sc2336_slave1_write_register(ViPipe, 0x4823, 0x03); + sc2336_slave1_write_register(ViPipe, 0x4825, 0x02); + sc2336_slave1_write_register(ViPipe, 0x4827, 0x03); + sc2336_slave1_write_register(ViPipe, 0x4829, 0x04); + sc2336_slave1_write_register(ViPipe, 0x5799, 0x06); + sc2336_slave1_write_register(ViPipe, 0x5ae0, 0xfe); + sc2336_slave1_write_register(ViPipe, 0x5ae1, 0x40); + sc2336_slave1_write_register(ViPipe, 0x5ae2, 0x30); + sc2336_slave1_write_register(ViPipe, 0x5ae3, 0x28); + sc2336_slave1_write_register(ViPipe, 0x5ae4, 0x20); + sc2336_slave1_write_register(ViPipe, 0x5ae5, 0x30); + sc2336_slave1_write_register(ViPipe, 0x5ae6, 0x28); + sc2336_slave1_write_register(ViPipe, 0x5ae7, 0x20); + sc2336_slave1_write_register(ViPipe, 0x5ae8, 0x3c); + sc2336_slave1_write_register(ViPipe, 0x5ae9, 0x30); + sc2336_slave1_write_register(ViPipe, 0x5aea, 0x28); + sc2336_slave1_write_register(ViPipe, 0x5aeb, 0x3c); + sc2336_slave1_write_register(ViPipe, 0x5aec, 0x30); + sc2336_slave1_write_register(ViPipe, 0x5aed, 0x28); + sc2336_slave1_write_register(ViPipe, 0x5aee, 0xfe); + sc2336_slave1_write_register(ViPipe, 0x5aef, 0x40); + sc2336_slave1_write_register(ViPipe, 0x5af4, 0x30); + sc2336_slave1_write_register(ViPipe, 0x5af5, 0x28); + sc2336_slave1_write_register(ViPipe, 0x5af6, 0x20); + sc2336_slave1_write_register(ViPipe, 0x5af7, 0x30); + sc2336_slave1_write_register(ViPipe, 0x5af8, 0x28); + sc2336_slave1_write_register(ViPipe, 0x5af9, 0x20); + sc2336_slave1_write_register(ViPipe, 0x5afa, 0x3c); + sc2336_slave1_write_register(ViPipe, 0x5afb, 0x30); + sc2336_slave1_write_register(ViPipe, 0x5afc, 0x28); + sc2336_slave1_write_register(ViPipe, 0x5afd, 0x3c); + sc2336_slave1_write_register(ViPipe, 0x5afe, 0x30); + sc2336_slave1_write_register(ViPipe, 0x5aff, 0x28); + sc2336_slave1_write_register(ViPipe, 0x36e9, 0x44); + sc2336_slave1_write_register(ViPipe, 0x37f9, 0x44); + sc2336_slave1_write_register(ViPipe, 0x0100, 0x01); + + //sc2336_slave1_default_reg_init(ViPipe); + + sc2336_slave1_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC2336 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p/Makefile new file mode 100644 index 00000000..5cdee09c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p/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_sc2336p.a +TARGET_SO = $(MW_LIB)/libsns_sc2336p.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p/sc2336p_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p/sc2336p_cmos.c new file mode 100644 index 00000000..27c5fb7b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p/sc2336p_cmos.c @@ -0,0 +1,905 @@ +#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 "sc2336p_cmos_ex.h" +#include "sc2336p_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 SC2336P_ID 35 +#define SENSOR_SC2336P_WIDTH 1920 +#define SENSOR_SC2336P_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC2336P[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC2336P_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC2336P[dev]) +#define SC2336P_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC2336P[dev] = pstCtx) +#define SC2336P_SENSOR_RESET_CTX(dev) (g_pastSC2336P[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC2336P_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC2336P_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC2336P_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +SC2336P_STATE_S g_astSC2336P_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); +/*****SC2336P Lines Range*****/ +#define SC2336P_FULL_LINES_MAX (0xFFFF) + +/*****SC2336P Register Address*****/ +#define SC2336P_SHS1_0_ADDR 0x3E00 +#define SC2336P_SHS1_1_ADDR 0x3E01 +#define SC2336P_SHS1_2_ADDR 0x3E02 +#define SC2336P_AGAIN0_ADDR 0x3E09 +#define SC2336P_DGAIN0_ADDR 0x3E06 +#define SC2336P_VMAX_ADDR 0x320E +#define SC2336P_TABLE_END 0xFFFF + +#define SC2336P_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 SC2336P_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC2336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC2336P_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 = SC2336P_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; +#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); + SC2336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC2336P_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC2336P_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC2336P_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC2336P_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 > SC2336P_FULL_LINES_MAX) ? SC2336P_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; + + SC2336P_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; + + SC2336P_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 SC2336P_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC2336P_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; + + SC2336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC2336P_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC2336P_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); + SC2336P_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_aunSC2336P_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 = sc2336p_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc2336p_addr_byte; + pstI2c_data[i].u32DataByteNum = sc2336p_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 = SC2336P_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC2336P_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC2336P_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC2336P_AGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC2336P_DGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC2336P_DGAIN0_ADDR + 1; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC2336P_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC2336P_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); + SC2336P_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 (SC2336P_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC2336P_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 SC2336P_MODE_S *pstMode = CVI_NULL; + + SC2336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC2336P_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC2336P_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; + + SC2336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc2336p_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC2336P_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC2336P_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 = &sc2336p_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 = sc2336p_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc2336p_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 sc2336p_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC2336P_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC2336P_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)); + + SC2336P_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC2336P_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC2336P_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 = SC2336P_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, SC2336P_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, SC2336P_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, SC2336P_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_au16SC2336P_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC2336P_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC2336P_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc2336p_standby, + .pfnRestart = sc2336p_restart, + .pfnMirrorFlip = sc2336p_mirror_flip, + .pfnWriteReg = sc2336p_write_register, + .pfnReadReg = sc2336p_read_register, + .pfnSetBusInfo = sc2336p_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 = sc2336p_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p/sc2336p_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p/sc2336p_cmos_ex.h new file mode 100644 index 00000000..45c005be --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p/sc2336p_cmos_ex.h @@ -0,0 +1,85 @@ +#ifndef __SC2336P_CMOS_EX_H_ +#define __SC2336P_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 sc2336p_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 _SC2336P_MODE_E { + SC2336P_MODE_1080P30 = 0, + SC2336P_MODE_LINEAR_NUM, + SC2336P_MODE_NUM +} SC2336P_MODE_E; + +typedef struct _SC2336P_STATE_S { + CVI_U32 u32Sexp_MAX; /* (2*{16’h3e23,16’h3e24} – 'd10)/2 */ +} SC2336P_STATE_S; + +typedef struct _SC2336P_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]; +} SC2336P_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC2336P[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC2336P_BusInfo[]; +extern CVI_U16 g_au16SC2336P_GainMode[]; +extern CVI_U16 g_au16SC2336P_L2SMode[]; +extern const CVI_U8 sc2336p_i2c_addr; +extern const CVI_U32 sc2336p_addr_byte; +extern const CVI_U32 sc2336p_data_byte; +extern void sc2336p_init(VI_PIPE ViPipe); +extern void sc2336p_exit(VI_PIPE ViPipe); +extern void sc2336p_standby(VI_PIPE ViPipe); +extern void sc2336p_restart(VI_PIPE ViPipe); +extern int sc2336p_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc2336p_read_register(VI_PIPE ViPipe, int addr); +extern void sc2336p_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc2336p_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC2336P_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p/sc2336p_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p/sc2336p_cmos_param.h new file mode 100644 index 00000000..feebdae9 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p/sc2336p_cmos_param.h @@ -0,0 +1,125 @@ +#ifndef __SC2336P_CMOS_PARAM_H_ +#define __SC2336P_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 "sc2336p_cmos_ex.h" + +static const SC2336P_MODE_S g_astSC2336P_mode[SC2336P_MODE_NUM] = { + [SC2336P_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 sc2336p_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 /* __SC2336P_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p/sc2336p_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p/sc2336p_sensor_ctl.c new file mode 100644 index 00000000..28af2ec0 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p/sc2336p_sensor_ctl.c @@ -0,0 +1,410 @@ +#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 "sc2336p_cmos_ex.h" + +static void sc2336p_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc2336p_i2c_addr = 0x30; /* I2C Address of SC2336P */ +const CVI_U32 sc2336p_addr_byte = 2; +const CVI_U32 sc2336p_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc2336p_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC2336P_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, sc2336p_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 sc2336p_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 sc2336p_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 (sc2336p_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc2336p_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, sc2336p_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc2336p_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 sc2336p_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 (sc2336p_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc2336p_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc2336p_addr_byte + sc2336p_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 sc2336p_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) + sc2336p_write_register(ViPipe, addr, data); + } +} + +void sc2336p_standby(VI_PIPE ViPipe) +{ + sc2336p_write_register(ViPipe, 0x0100, 0x00); +} + +void sc2336p_restart(VI_PIPE ViPipe) +{ + sc2336p_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc2336p_write_register(ViPipe, 0x0100, 0x01); +} + +void sc2336p_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC2336P[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc2336p_write_register(ViPipe, + g_pastSC2336P[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC2336P[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define SC2336P_CHIP_ID_HI_ADDR 0x3107 +#define SC2336P_CHIP_ID_LO_ADDR 0x3108 +#define SC2336P_CHIP_ID 0x9b3a + +void sc2336p_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; + } + + sc2336p_write_register(ViPipe, 0x3221, val); +} + +int sc2336p_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc2336p_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc2336p_read_register(ViPipe, SC2336P_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 = sc2336p_read_register(ViPipe, SC2336P_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 != SC2336P_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + return CVI_SUCCESS; +} + + +void sc2336p_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + + bInit = g_pastSC2336P[ViPipe]->bInit; + enWDRMode = g_pastSC2336P[ViPipe]->enWDRMode; + + sc2336p_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_NONE) { + sc2336p_linear_1080p30_init(ViPipe); + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_NONE) { + sc2336p_linear_1080p30_init(ViPipe); + } + } + g_pastSC2336P[ViPipe]->bInit = CVI_TRUE; +} + +void sc2336p_exit(VI_PIPE ViPipe) +{ + sc2336p_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void sc2336p_linear_1080p30_init(VI_PIPE ViPipe) +{ + sc2336p_write_register(ViPipe, 0x0103, 0x01); + sc2336p_write_register(ViPipe, 0x0100, 0x00); + sc2336p_write_register(ViPipe, 0x36e9, 0x80); + sc2336p_write_register(ViPipe, 0x37f9, 0x80); + sc2336p_write_register(ViPipe, 0x301f, 0x02); + sc2336p_write_register(ViPipe, 0x3106, 0x05); + sc2336p_write_register(ViPipe, 0x3248, 0x04); + sc2336p_write_register(ViPipe, 0x3249, 0x0b); + sc2336p_write_register(ViPipe, 0x3253, 0x08); + sc2336p_write_register(ViPipe, 0x3301, 0x09); + sc2336p_write_register(ViPipe, 0x3302, 0xff); + sc2336p_write_register(ViPipe, 0x3303, 0x10); + sc2336p_write_register(ViPipe, 0x3306, 0x80); + sc2336p_write_register(ViPipe, 0x3307, 0x02); + sc2336p_write_register(ViPipe, 0x3309, 0xc8); + sc2336p_write_register(ViPipe, 0x330a, 0x01); + sc2336p_write_register(ViPipe, 0x330b, 0x30); + sc2336p_write_register(ViPipe, 0x330c, 0x16); + sc2336p_write_register(ViPipe, 0x330d, 0xff); + sc2336p_write_register(ViPipe, 0x3318, 0x02); + sc2336p_write_register(ViPipe, 0x331f, 0xb9); + sc2336p_write_register(ViPipe, 0x3321, 0x0a); + sc2336p_write_register(ViPipe, 0x3327, 0x0e); + sc2336p_write_register(ViPipe, 0x332b, 0x12); + sc2336p_write_register(ViPipe, 0x3333, 0x10); + sc2336p_write_register(ViPipe, 0x3334, 0x40); + sc2336p_write_register(ViPipe, 0x335e, 0x06); + sc2336p_write_register(ViPipe, 0x335f, 0x0a); + sc2336p_write_register(ViPipe, 0x3364, 0x1f); + sc2336p_write_register(ViPipe, 0x337c, 0x02); + sc2336p_write_register(ViPipe, 0x337d, 0x0e); + sc2336p_write_register(ViPipe, 0x3390, 0x09); + sc2336p_write_register(ViPipe, 0x3391, 0x0f); + sc2336p_write_register(ViPipe, 0x3392, 0x1f); + sc2336p_write_register(ViPipe, 0x3393, 0x20); + sc2336p_write_register(ViPipe, 0x3394, 0x20); + sc2336p_write_register(ViPipe, 0x3395, 0xe0); + sc2336p_write_register(ViPipe, 0x33a2, 0x04); + sc2336p_write_register(ViPipe, 0x33b1, 0x80); + sc2336p_write_register(ViPipe, 0x33b2, 0x68); + sc2336p_write_register(ViPipe, 0x33b3, 0x42); + sc2336p_write_register(ViPipe, 0x33f9, 0x90); + sc2336p_write_register(ViPipe, 0x33fb, 0xd0); + sc2336p_write_register(ViPipe, 0x33fc, 0x0f); + sc2336p_write_register(ViPipe, 0x33fd, 0x1f); + sc2336p_write_register(ViPipe, 0x349f, 0x03); + sc2336p_write_register(ViPipe, 0x34a6, 0x0f); + sc2336p_write_register(ViPipe, 0x34a7, 0x1f); + sc2336p_write_register(ViPipe, 0x34a8, 0x42); + sc2336p_write_register(ViPipe, 0x34a9, 0x18); + sc2336p_write_register(ViPipe, 0x34aa, 0x01); + sc2336p_write_register(ViPipe, 0x34ab, 0x43); + sc2336p_write_register(ViPipe, 0x34ac, 0x01); + sc2336p_write_register(ViPipe, 0x34ad, 0x80); + sc2336p_write_register(ViPipe, 0x3630, 0xf4); + sc2336p_write_register(ViPipe, 0x3632, 0x44); + sc2336p_write_register(ViPipe, 0x3633, 0x22); + sc2336p_write_register(ViPipe, 0x3639, 0xf4); + sc2336p_write_register(ViPipe, 0x363c, 0x47); + sc2336p_write_register(ViPipe, 0x3670, 0x09); + sc2336p_write_register(ViPipe, 0x3674, 0xf4); + sc2336p_write_register(ViPipe, 0x3675, 0xfb); + sc2336p_write_register(ViPipe, 0x3676, 0xed); + sc2336p_write_register(ViPipe, 0x367c, 0x09); + sc2336p_write_register(ViPipe, 0x367d, 0x0f); + sc2336p_write_register(ViPipe, 0x3690, 0x22); + sc2336p_write_register(ViPipe, 0x3691, 0x22); + sc2336p_write_register(ViPipe, 0x3692, 0x22); + sc2336p_write_register(ViPipe, 0x3698, 0x89); + sc2336p_write_register(ViPipe, 0x3699, 0x96); + sc2336p_write_register(ViPipe, 0x369a, 0xd0); + sc2336p_write_register(ViPipe, 0x369b, 0xd0); + sc2336p_write_register(ViPipe, 0x369c, 0x09); + sc2336p_write_register(ViPipe, 0x369d, 0x0f); + sc2336p_write_register(ViPipe, 0x36a2, 0x09); + sc2336p_write_register(ViPipe, 0x36a3, 0x0f); + sc2336p_write_register(ViPipe, 0x36a4, 0x1f); + sc2336p_write_register(ViPipe, 0x36d0, 0x01); + sc2336p_write_register(ViPipe, 0x3722, 0x81); + sc2336p_write_register(ViPipe, 0x3724, 0x41); + sc2336p_write_register(ViPipe, 0x3725, 0xc1); + sc2336p_write_register(ViPipe, 0x3728, 0x20); + sc2336p_write_register(ViPipe, 0x3900, 0x0d); + sc2336p_write_register(ViPipe, 0x3905, 0x98); + sc2336p_write_register(ViPipe, 0x391b, 0x81); + sc2336p_write_register(ViPipe, 0x391c, 0x10); + sc2336p_write_register(ViPipe, 0x3933, 0x81); + sc2336p_write_register(ViPipe, 0x3934, 0xd0); + sc2336p_write_register(ViPipe, 0x3940, 0x75); + sc2336p_write_register(ViPipe, 0x3941, 0x00); + sc2336p_write_register(ViPipe, 0x3942, 0x01); + sc2336p_write_register(ViPipe, 0x3943, 0xd1); + sc2336p_write_register(ViPipe, 0x3952, 0x02); + sc2336p_write_register(ViPipe, 0x3953, 0x0f); + sc2336p_write_register(ViPipe, 0x3e01, 0x45); + sc2336p_write_register(ViPipe, 0x3e02, 0xf0); + sc2336p_write_register(ViPipe, 0x3e08, 0x1f); + sc2336p_write_register(ViPipe, 0x3e1b, 0x14); + sc2336p_write_register(ViPipe, 0x440e, 0x02); + sc2336p_write_register(ViPipe, 0x4509, 0x38); + sc2336p_write_register(ViPipe, 0x5799, 0x06); + sc2336p_write_register(ViPipe, 0x5ae0, 0xfe); + sc2336p_write_register(ViPipe, 0x5ae1, 0x40); + sc2336p_write_register(ViPipe, 0x5ae2, 0x30); + sc2336p_write_register(ViPipe, 0x5ae3, 0x28); + sc2336p_write_register(ViPipe, 0x5ae4, 0x20); + sc2336p_write_register(ViPipe, 0x5ae5, 0x30); + sc2336p_write_register(ViPipe, 0x5ae6, 0x28); + sc2336p_write_register(ViPipe, 0x5ae7, 0x20); + sc2336p_write_register(ViPipe, 0x5ae8, 0x3c); + sc2336p_write_register(ViPipe, 0x5ae9, 0x30); + sc2336p_write_register(ViPipe, 0x5aea, 0x28); + sc2336p_write_register(ViPipe, 0x5aeb, 0x3c); + sc2336p_write_register(ViPipe, 0x5aec, 0x30); + sc2336p_write_register(ViPipe, 0x5aed, 0x28); + sc2336p_write_register(ViPipe, 0x5aee, 0xfe); + sc2336p_write_register(ViPipe, 0x5aef, 0x40); + sc2336p_write_register(ViPipe, 0x5af4, 0x30); + sc2336p_write_register(ViPipe, 0x5af5, 0x28); + sc2336p_write_register(ViPipe, 0x5af6, 0x20); + sc2336p_write_register(ViPipe, 0x5af7, 0x30); + sc2336p_write_register(ViPipe, 0x5af8, 0x28); + sc2336p_write_register(ViPipe, 0x5af9, 0x20); + sc2336p_write_register(ViPipe, 0x5afa, 0x3c); + sc2336p_write_register(ViPipe, 0x5afb, 0x30); + sc2336p_write_register(ViPipe, 0x5afc, 0x28); + sc2336p_write_register(ViPipe, 0x5afd, 0x3c); + sc2336p_write_register(ViPipe, 0x5afe, 0x30); + sc2336p_write_register(ViPipe, 0x5aff, 0x28); + sc2336p_write_register(ViPipe, 0x36e9, 0x20); + sc2336p_write_register(ViPipe, 0x37f9, 0x27); + + sc2336p_default_reg_init(ViPipe); + + sc2336p_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC2336P 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p_1L/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p_1L/Makefile new file mode 100644 index 00000000..79ededd2 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p_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_sc2336p_1l.a +TARGET_SO = $(MW_LIB)/libsns_sc2336p_1l.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p_1L/sc2336p_1L_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p_1L/sc2336p_1L_cmos.c new file mode 100644 index 00000000..48798d48 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p_1L/sc2336p_1L_cmos.c @@ -0,0 +1,905 @@ +#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 "sc2336p_1L_cmos_ex.h" +#include "sc2336p_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 SC2336P_1L_ID 35 +#define SENSOR_SC2336P_1L_WIDTH 1920 +#define SENSOR_SC2336P_1L_HEIGHT 1080 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC2336P_1L[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC2336P_1L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC2336P_1L[dev]) +#define SC2336P_1L_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC2336P_1L[dev] = pstCtx) +#define SC2336P_1L_SENSOR_RESET_CTX(dev) (g_pastSC2336P_1L[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC2336P_1L_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC2336P_1L_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC2336P_1L_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +SC2336P_1L_STATE_S g_astSC2336P_1L_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); +/*****SC2336P_1L Lines Range*****/ +#define SC2336P_1L_FULL_LINES_MAX (0xFFFF) + +/*****SC2336P_1L Register Address*****/ +#define SC2336P_1L_SHS1_0_ADDR 0x3E00 +#define SC2336P_1L_SHS1_1_ADDR 0x3E01 +#define SC2336P_1L_SHS1_2_ADDR 0x3E02 +#define SC2336P_1L_AGAIN0_ADDR 0x3E09 +#define SC2336P_1L_DGAIN0_ADDR 0x3E06 +#define SC2336P_1L_VMAX_ADDR 0x320E +#define SC2336P_1L_TABLE_END 0xFFFF + +#define SC2336P_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 SC2336P_1L_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC2336P_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC2336P_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 = SC2336P_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_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; +#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); + SC2336P_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC2336P_1L_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC2336P_1L_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC2336P_1L_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC2336P_1L_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 > SC2336P_1L_FULL_LINES_MAX) ? SC2336P_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_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; + + SC2336P_1L_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; + + SC2336P_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 */ + + /* 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 SC2336P_1L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC2336P_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC2336P_1L_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; + + SC2336P_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC2336P_1L_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC2336P_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); + SC2336P_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_aunSC2336P_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 = sc2336p_1L_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc2336p_1L_addr_byte; + pstI2c_data[i].u32DataByteNum = sc2336p_1L_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 = SC2336P_1L_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC2336P_1L_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC2336P_1L_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC2336P_1L_AGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC2336P_1L_DGAIN0_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC2336P_1L_DGAIN0_ADDR + 1; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC2336P_1L_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC2336P_1L_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); + SC2336P_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 (SC2336P_1L_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC2336P_1L_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 SC2336P_1L_MODE_S *pstMode = CVI_NULL; + + SC2336P_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC2336P_1L_MODE_1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC2336P_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; + + SC2336P_1L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc2336p_1L_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC2336P_1L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC2336P_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 = &sc2336p_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 = sc2336p_1L_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc2336p_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 sc2336p_1L_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC2336P_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; + + SC2336P_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)); + + SC2336P_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; + + SC2336P_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC2336P_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 = SC2336P_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, SC2336P_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, SC2336P_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, SC2336P_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_au16SC2336P_1L_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC2336P_1L_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC2336P_1L_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc2336p_1L_standby, + .pfnRestart = sc2336p_1L_restart, + .pfnMirrorFlip = sc2336p_1L_mirror_flip, + .pfnWriteReg = sc2336p_1L_write_register, + .pfnReadReg = sc2336p_1L_read_register, + .pfnSetBusInfo = sc2336p_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 = sc2336p_1L_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p_1L/sc2336p_1L_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p_1L/sc2336p_1L_cmos_ex.h new file mode 100644 index 00000000..ea2c5d37 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p_1L/sc2336p_1L_cmos_ex.h @@ -0,0 +1,85 @@ +#ifndef __SC2336P_1L_CMOS_EX_H_ +#define __SC2336P_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 sc2336p_1L_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 _SC2336P_1L_MODE_E { + SC2336P_1L_MODE_1080P30 = 0, + SC2336P_1L_MODE_LINEAR_NUM, + SC2336P_1L_MODE_NUM +} SC2336P_1L_MODE_E; + +typedef struct _SC2336P_1L_STATE_S { + CVI_U32 u32Sexp_MAX; /* (2*{16’h3e23,16’h3e24} – 'd10)/2 */ +} SC2336P_1L_STATE_S; + +typedef struct _SC2336P_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_S stAgain[2]; + SNS_ATTR_S stDgain[2]; + CVI_U16 u16SexpMaxReg; /* {16’h3e23,16’h3e24} */ + char name[64]; +} SC2336P_1L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC2336P_1L[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC2336P_1L_BusInfo[]; +extern CVI_U16 g_au16SC2336P_1L_GainMode[]; +extern CVI_U16 g_au16SC2336P_1L_L2SMode[]; +extern const CVI_U8 sc2336p_1L_i2c_addr; +extern const CVI_U32 sc2336p_1L_addr_byte; +extern const CVI_U32 sc2336p_1L_data_byte; +extern void sc2336p_1L_init(VI_PIPE ViPipe); +extern void sc2336p_1L_exit(VI_PIPE ViPipe); +extern void sc2336p_1L_standby(VI_PIPE ViPipe); +extern void sc2336p_1L_restart(VI_PIPE ViPipe); +extern int sc2336p_1L_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc2336p_1L_read_register(VI_PIPE ViPipe, int addr); +extern void sc2336p_1L_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc2336p_1L_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC2336P_1L_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p_1L/sc2336p_1L_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p_1L/sc2336p_1L_cmos_param.h new file mode 100644 index 00000000..60c9a6f6 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p_1L/sc2336p_1L_cmos_param.h @@ -0,0 +1,125 @@ +#ifndef __SC2336P_1L_CMOS_PARAM_H_ +#define __SC2336P_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 "sc2336p_1L_cmos_ex.h" + +static const SC2336P_1L_MODE_S g_astSC2336P_1L_mode[SC2336P_1L_MODE_NUM] = { + [SC2336P_1L_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 sc2336p_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, + .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 /* __SC2336P_1L_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p_1L/sc2336p_1L_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p_1L/sc2336p_1L_sensor_ctl.c new file mode 100644 index 00000000..632b6907 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc2336p_1L/sc2336p_1L_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 "sc2336p_1L_cmos_ex.h" + +static void sc2336p_1L_linear_1080p30_init(VI_PIPE ViPipe); + +const CVI_U8 sc2336p_1L_i2c_addr = 0x30; /* I2C Address of SC2336P */ +const CVI_U32 sc2336p_1L_addr_byte = 2; +const CVI_U32 sc2336p_1L_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc2336p_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_aunSC2336P_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, sc2336p_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 sc2336p_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 sc2336p_1L_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 (sc2336p_1L_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc2336p_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, sc2336p_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 (sc2336p_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 sc2336p_1L_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 (sc2336p_1L_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc2336p_1L_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc2336p_1L_addr_byte + sc2336p_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 sc2336p_1L_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) + sc2336p_1L_write_register(ViPipe, addr, data); + } +} + +void sc2336p_1L_standby(VI_PIPE ViPipe) +{ + sc2336p_1L_write_register(ViPipe, 0x0100, 0x00); +} + +void sc2336p_1L_restart(VI_PIPE ViPipe) +{ + sc2336p_1L_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc2336p_1L_write_register(ViPipe, 0x0100, 0x01); +} + +void sc2336p_1L_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC2336P_1L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc2336p_1L_write_register(ViPipe, + g_pastSC2336P_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC2336P_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define SC2336P_1L_CHIP_ID_HI_ADDR 0x3107 +#define SC2336P_1L_CHIP_ID_LO_ADDR 0x3108 +#define SC2336P_1L_CHIP_ID 0x9b3a + +void sc2336p_1L_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; + } + + sc2336p_1L_write_register(ViPipe, 0x3221, val); +} + +int sc2336p_1L_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (sc2336p_1L_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + sc2336p_1L_write_register(ViPipe, 0x301a, 0xf8); + sc2336p_1L_write_register(ViPipe, 0x0100, 0x01); + delay_ms(5); + + nVal = sc2336p_1L_read_register(ViPipe, SC2336P_1L_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 = sc2336p_1L_read_register(ViPipe, SC2336P_1L_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 != SC2336P_1L_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + return CVI_SUCCESS; +} + + +void sc2336p_1L_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + + bInit = g_pastSC2336P_1L[ViPipe]->bInit; + enWDRMode = g_pastSC2336P_1L[ViPipe]->enWDRMode; + + sc2336p_1L_i2c_init(ViPipe); + + /* When sensor first init, config all registers */ + if (bInit == CVI_FALSE) { + if (enWDRMode == WDR_MODE_NONE) { + sc2336p_1L_linear_1080p30_init(ViPipe); + } + } + /* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */ + else { + if (enWDRMode == WDR_MODE_NONE) { + sc2336p_1L_linear_1080p30_init(ViPipe); + } + } + g_pastSC2336P_1L[ViPipe]->bInit = CVI_TRUE; +} + +void sc2336p_1L_exit(VI_PIPE ViPipe) +{ + sc2336p_1L_i2c_exit(ViPipe); +} + +/* 1080P30 and 1080P25 */ +static void sc2336p_1L_linear_1080p30_init(VI_PIPE ViPipe) +{ + sc2336p_1L_write_register(ViPipe, 0x0103,0x01); + sc2336p_1L_write_register(ViPipe, 0x0100,0x00); + sc2336p_1L_write_register(ViPipe, 0x36e9,0x80); + sc2336p_1L_write_register(ViPipe, 0x37f9,0x80); + sc2336p_1L_write_register(ViPipe, 0x3018,0x12); + sc2336p_1L_write_register(ViPipe, 0x3019,0x0e); + sc2336p_1L_write_register(ViPipe, 0x301f,0x17); + sc2336p_1L_write_register(ViPipe, 0x3106,0x05); + sc2336p_1L_write_register(ViPipe, 0x3248,0x04); + sc2336p_1L_write_register(ViPipe, 0x3249,0x0b); + sc2336p_1L_write_register(ViPipe, 0x3253,0x08); + sc2336p_1L_write_register(ViPipe, 0x3301,0x09); + sc2336p_1L_write_register(ViPipe, 0x3302,0xff); + sc2336p_1L_write_register(ViPipe, 0x3303,0x10); + sc2336p_1L_write_register(ViPipe, 0x3306,0x80); + sc2336p_1L_write_register(ViPipe, 0x3307,0x02); + sc2336p_1L_write_register(ViPipe, 0x3309,0xc8); + sc2336p_1L_write_register(ViPipe, 0x330a,0x01); + sc2336p_1L_write_register(ViPipe, 0x330b,0x30); + sc2336p_1L_write_register(ViPipe, 0x330c,0x16); + sc2336p_1L_write_register(ViPipe, 0x330d,0xff); + sc2336p_1L_write_register(ViPipe, 0x3318,0x02); + sc2336p_1L_write_register(ViPipe, 0x331f,0xb9); + sc2336p_1L_write_register(ViPipe, 0x3321,0x0a); + sc2336p_1L_write_register(ViPipe, 0x3327,0x0e); + sc2336p_1L_write_register(ViPipe, 0x332b,0x12); + sc2336p_1L_write_register(ViPipe, 0x3333,0x10); + sc2336p_1L_write_register(ViPipe, 0x3334,0x40); + sc2336p_1L_write_register(ViPipe, 0x335e,0x06); + sc2336p_1L_write_register(ViPipe, 0x335f,0x0a); + sc2336p_1L_write_register(ViPipe, 0x3364,0x1f); + sc2336p_1L_write_register(ViPipe, 0x337c,0x02); + sc2336p_1L_write_register(ViPipe, 0x337d,0x0e); + sc2336p_1L_write_register(ViPipe, 0x3390,0x09); + sc2336p_1L_write_register(ViPipe, 0x3391,0x0f); + sc2336p_1L_write_register(ViPipe, 0x3392,0x1f); + sc2336p_1L_write_register(ViPipe, 0x3393,0x20); + sc2336p_1L_write_register(ViPipe, 0x3394,0x20); + sc2336p_1L_write_register(ViPipe, 0x3395,0xe0); + sc2336p_1L_write_register(ViPipe, 0x33a2,0x04); + sc2336p_1L_write_register(ViPipe, 0x33b1,0x80); + sc2336p_1L_write_register(ViPipe, 0x33b2,0x68); + sc2336p_1L_write_register(ViPipe, 0x33b3,0x42); + sc2336p_1L_write_register(ViPipe, 0x33f9,0x90); + sc2336p_1L_write_register(ViPipe, 0x33fb,0xd0); + sc2336p_1L_write_register(ViPipe, 0x33fc,0x0f); + sc2336p_1L_write_register(ViPipe, 0x33fd,0x1f); + sc2336p_1L_write_register(ViPipe, 0x349f,0x03); + sc2336p_1L_write_register(ViPipe, 0x34a6,0x0f); + sc2336p_1L_write_register(ViPipe, 0x34a7,0x1f); + sc2336p_1L_write_register(ViPipe, 0x34a8,0x42); + sc2336p_1L_write_register(ViPipe, 0x34a9,0x18); + sc2336p_1L_write_register(ViPipe, 0x34aa,0x01); + sc2336p_1L_write_register(ViPipe, 0x34ab,0x43); + sc2336p_1L_write_register(ViPipe, 0x34ac,0x01); + sc2336p_1L_write_register(ViPipe, 0x34ad,0x80); + sc2336p_1L_write_register(ViPipe, 0x3630,0xf4); + sc2336p_1L_write_register(ViPipe, 0x3632,0x44); + sc2336p_1L_write_register(ViPipe, 0x3633,0x22); + sc2336p_1L_write_register(ViPipe, 0x3639,0xf4); + sc2336p_1L_write_register(ViPipe, 0x363c,0x47); + sc2336p_1L_write_register(ViPipe, 0x3670,0x09); + sc2336p_1L_write_register(ViPipe, 0x3674,0xf4); + sc2336p_1L_write_register(ViPipe, 0x3675,0xfb); + sc2336p_1L_write_register(ViPipe, 0x3676,0xed); + sc2336p_1L_write_register(ViPipe, 0x367c,0x09); + sc2336p_1L_write_register(ViPipe, 0x367d,0x0f); + sc2336p_1L_write_register(ViPipe, 0x3690,0x22); + sc2336p_1L_write_register(ViPipe, 0x3691,0x22); + sc2336p_1L_write_register(ViPipe, 0x3692,0x22); + sc2336p_1L_write_register(ViPipe, 0x3698,0x89); + sc2336p_1L_write_register(ViPipe, 0x3699,0x96); + sc2336p_1L_write_register(ViPipe, 0x369a,0xd0); + sc2336p_1L_write_register(ViPipe, 0x369b,0xd0); + sc2336p_1L_write_register(ViPipe, 0x369c,0x09); + sc2336p_1L_write_register(ViPipe, 0x369d,0x0f); + sc2336p_1L_write_register(ViPipe, 0x36a2,0x09); + sc2336p_1L_write_register(ViPipe, 0x36a3,0x0f); + sc2336p_1L_write_register(ViPipe, 0x36a4,0x1f); + sc2336p_1L_write_register(ViPipe, 0x36d0,0x01); + sc2336p_1L_write_register(ViPipe, 0x36ec,0x0c); + sc2336p_1L_write_register(ViPipe, 0x3722,0xc1); + sc2336p_1L_write_register(ViPipe, 0x3724,0x41); + sc2336p_1L_write_register(ViPipe, 0x3725,0xc1); + sc2336p_1L_write_register(ViPipe, 0x3728,0x20); + sc2336p_1L_write_register(ViPipe, 0x3900,0x0d); + sc2336p_1L_write_register(ViPipe, 0x3905,0x98); + sc2336p_1L_write_register(ViPipe, 0x3919,0x04); + sc2336p_1L_write_register(ViPipe, 0x391b,0x81); + sc2336p_1L_write_register(ViPipe, 0x391c,0x10); + sc2336p_1L_write_register(ViPipe, 0x3933,0x81); + sc2336p_1L_write_register(ViPipe, 0x3934,0xd0); + sc2336p_1L_write_register(ViPipe, 0x3940,0x75); + sc2336p_1L_write_register(ViPipe, 0x3941,0x00); + sc2336p_1L_write_register(ViPipe, 0x3942,0x01); + sc2336p_1L_write_register(ViPipe, 0x3943,0xd1); + sc2336p_1L_write_register(ViPipe, 0x3952,0x02); + sc2336p_1L_write_register(ViPipe, 0x3953,0x0f); + sc2336p_1L_write_register(ViPipe, 0x3e01,0x45); + sc2336p_1L_write_register(ViPipe, 0x3e02,0xf0); + sc2336p_1L_write_register(ViPipe, 0x3e08,0x1f); + sc2336p_1L_write_register(ViPipe, 0x3e1b,0x14); + sc2336p_1L_write_register(ViPipe, 0x440e,0x02); + sc2336p_1L_write_register(ViPipe, 0x4509,0x38); + sc2336p_1L_write_register(ViPipe, 0x5799,0x06); + sc2336p_1L_write_register(ViPipe, 0x5ae0,0xfe); + sc2336p_1L_write_register(ViPipe, 0x5ae1,0x40); + sc2336p_1L_write_register(ViPipe, 0x5ae2,0x30); + sc2336p_1L_write_register(ViPipe, 0x5ae3,0x28); + sc2336p_1L_write_register(ViPipe, 0x5ae4,0x20); + sc2336p_1L_write_register(ViPipe, 0x5ae5,0x30); + sc2336p_1L_write_register(ViPipe, 0x5ae6,0x28); + sc2336p_1L_write_register(ViPipe, 0x5ae7,0x20); + sc2336p_1L_write_register(ViPipe, 0x5ae8,0x3c); + sc2336p_1L_write_register(ViPipe, 0x5ae9,0x30); + sc2336p_1L_write_register(ViPipe, 0x5aea,0x28); + sc2336p_1L_write_register(ViPipe, 0x5aeb,0x3c); + sc2336p_1L_write_register(ViPipe, 0x5aec,0x30); + sc2336p_1L_write_register(ViPipe, 0x5aed,0x28); + sc2336p_1L_write_register(ViPipe, 0x5aee,0xfe); + sc2336p_1L_write_register(ViPipe, 0x5aef,0x40); + sc2336p_1L_write_register(ViPipe, 0x5af4,0x30); + sc2336p_1L_write_register(ViPipe, 0x5af5,0x28); + sc2336p_1L_write_register(ViPipe, 0x5af6,0x20); + sc2336p_1L_write_register(ViPipe, 0x5af7,0x30); + sc2336p_1L_write_register(ViPipe, 0x5af8,0x28); + sc2336p_1L_write_register(ViPipe, 0x5af9,0x20); + sc2336p_1L_write_register(ViPipe, 0x5afa,0x3c); + sc2336p_1L_write_register(ViPipe, 0x5afb,0x30); + sc2336p_1L_write_register(ViPipe, 0x5afc,0x28); + sc2336p_1L_write_register(ViPipe, 0x5afd,0x3c); + sc2336p_1L_write_register(ViPipe, 0x5afe,0x30); + sc2336p_1L_write_register(ViPipe, 0x5aff,0x28); + sc2336p_1L_write_register(ViPipe, 0x36e9,0x20); + sc2336p_1L_write_register(ViPipe, 0x37f9,0x27); + + sc2336p_1L_default_reg_init(ViPipe); + + sc2336p_1L_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC2336P_1L 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc301iot/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc301iot/Makefile new file mode 100644 index 00000000..cf1e22a0 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc301iot/sc301iot_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc301iot/sc301iot_cmos.c new file mode 100644 index 00000000..1b5072f5 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc301iot/sc301iot_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc301iot/sc301iot_cmos_ex.h new file mode 100644 index 00000000..9a604568 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc301iot/sc301iot_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc301iot/sc301iot_cmos_param.h new file mode 100644 index 00000000..f8a1f284 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc301iot/sc301iot_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc301iot/sc301iot_sensor_ctl.c new file mode 100644 index 00000000..fcb6494c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3332/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3332/Makefile new file mode 100644 index 00000000..90edabd6 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3332/sc3332_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3332/sc3332_cmos.c new file mode 100644 index 00000000..9c1fd54e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3332/sc3332_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3332/sc3332_cmos_ex.h new file mode 100644 index 00000000..99f3443a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3332/sc3332_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3332/sc3332_cmos_param.h new file mode 100644 index 00000000..fb991d11 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3332/sc3332_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3332/sc3332_sensor_ctl.c new file mode 100644 index 00000000..d8b92b8a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3335/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3335/Makefile new file mode 100644 index 00000000..3275dbe5 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3335/sc3335_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3335/sc3335_cmos.c new file mode 100644 index 00000000..c1d44d07 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3335/sc3335_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3335/sc3335_cmos_ex.h new file mode 100644 index 00000000..8dc546b1 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3335/sc3335_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3335/sc3335_cmos_param.h new file mode 100644 index 00000000..138b6085 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3335/sc3335_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3335/sc3335_sensor_ctl.c new file mode 100644 index 00000000..a30ee121 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336/Makefile new file mode 100644 index 00000000..b6eacab4 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336/sc3336_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336/sc3336_cmos.c new file mode 100644 index 00000000..8f1535fc --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336/sc3336_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336/sc3336_cmos_ex.h new file mode 100644 index 00000000..9f055746 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336/sc3336_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336/sc3336_cmos_param.h new file mode 100644 index 00000000..f3d2a462 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336/sc3336_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336/sc3336_sensor_ctl.c new file mode 100644 index 00000000..8baf914e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336p/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336p/Makefile new file mode 100644 index 00000000..6ef9b6e9 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336p/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_sc3336p.a +TARGET_SO = $(MW_LIB)/libsns_sc3336p.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336p/sc3336p_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336p/sc3336p_cmos.c new file mode 100644 index 00000000..75d7cdc2 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336p/sc3336p_cmos.c @@ -0,0 +1,937 @@ +#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 "sc3336p_cmos_ex.h" +#include "sc3336p_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 SC3336P_ID 3336 +#define SC3336P_I2C_ADDR_1 0x30 +#define SC3336P_I2C_ADDR_2 0x32 +#define SC3336P_I2C_ADDR_IS_VALID(addr) ((addr) == SC3336P_I2C_ADDR_1 || (addr) == SC3336P_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC3336P[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC3336P_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC3336P[dev]) +#define SC3336P_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC3336P[dev] = pstCtx) +#define SC3336P_SENSOR_RESET_CTX(dev) (g_pastSC3336P[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC3336P_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 2}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC3336P_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC3336P_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc3336p_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); +/*****SC3336P Lines Range*****/ +#define SC3336P_FULL_LINES_MAX (0x7FFF) + +/*****SC3336P Register Address*****/ +#define SC3336P_EXP_H_ADDR (0x3e00) +#define SC3336P_EXP_M_ADDR (0x3e01) +#define SC3336P_EXP_L_ADDR (0x3e02) + +#define SC3336P_AGAIN_ADDR (0x3e09) + +#define SC3336P_DGAIN_H_ADDR (0x3e06) +#define SC3336P_DGAIN_L_ADDR (0x3e07) + +#define SC3336P_VMAX_H_ADDR (0x320e) +#define SC3336P_VMAX_L_ADDR (0x320f) + +#define SC3336P_RES_IS_1296P(w, h) ((w) == 2304 && (h) == 1296) + +#define SC3336P_EXPACCURACY (1) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + const SC3336P_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + SC3336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astSC3336P_mode[pstSnsState->u8ImgMode]; + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC3336P_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = SC3336P_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); + SC3336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC3336P_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC3336P_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC3336P_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC3336P_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 > SC3336P_FULL_LINES_MAX) ? SC3336P_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; + + SC3336P_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; + + SC3336P_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 SC3336P_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC3336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC3336P_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; + + SC3336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC3336P_MODE_2304X1296P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC3336P_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); + SC3336P_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_aunSC3336P_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 = sc3336p_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc3336p_addr_byte; + pstI2c_data[i].u32DataByteNum = sc3336p_data_byte; + } + + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC3336P_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_M_ADDR].u32RegAddr = SC3336P_EXP_M_ADDR; + pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC3336P_EXP_L_ADDR; + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = SC3336P_AGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC3336P_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC3336P_DGAIN_L_ADDR; + pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC3336P_VMAX_H_ADDR; + pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC3336P_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); + SC3336P_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 (SC3336P_RES_IS_1296P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC3336P_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; + + SC3336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeSc3336p_MirrorFip[ViPipe] != eSnsMirrorFlip) { + sc3336p_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeSc3336p_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC3336P_MODE_S *pstMode = CVI_NULL; + + SC3336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC3336P_MODE_2304X1296P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC3336P_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; + + SC3336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc3336p_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC3336P_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC3336P_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 = &sc3336p_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 = sc3336p_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc3336p_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 (SC3336P_I2C_ADDR_IS_VALID(s32I2cAddr)) + sc3336p_i2c_addr = s32I2cAddr; +} + +static CVI_S32 sc3336p_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC3336P_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC3336P_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)); + + SC3336P_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC3336P_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC3336P_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 = SC3336P_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, SC3336P_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, SC3336P_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, SC3336P_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_au16SC3336P_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC3336P_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC3336P_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc3336p_standby, + .pfnRestart = sc3336p_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = sc3336p_write_register, + .pfnReadReg = sc3336p_read_register, + .pfnSetBusInfo = sc3336p_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 = sc3336p_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336p/sc3336p_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336p/sc3336p_cmos_ex.h new file mode 100644 index 00000000..054bda7d --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336p/sc3336p_cmos_ex.h @@ -0,0 +1,80 @@ +#ifndef __SC3336P_CMOS_EX_H_ +#define __SC3336P_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 sc3336p_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 _SC3336P_MODE_E { + SC3336P_MODE_2304X1296P30 = 0, + SC3336P_MODE_LINEAR_NUM, + SC3336P_MODE_2304X1296P30_WDR = SC3336P_MODE_LINEAR_NUM, + SC3336P_MODE_NUM +} SC3336P_MODE_E; + +typedef struct _SC3336P_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]; +} SC3336P_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC3336P[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC3336P_BusInfo[]; +extern CVI_U16 g_au16SC3336P_GainMode[]; +extern CVI_U16 g_au16SC3336P_L2SMode[]; +extern CVI_U8 sc3336p_i2c_addr; +extern const CVI_U32 sc3336p_addr_byte; +extern const CVI_U32 sc3336p_data_byte; +extern void sc3336p_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern void sc3336p_init(VI_PIPE ViPipe); +extern void sc3336p_exit(VI_PIPE ViPipe); +extern void sc3336p_standby(VI_PIPE ViPipe); +extern void sc3336p_restart(VI_PIPE ViPipe); +extern int sc3336p_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc3336p_read_register(VI_PIPE ViPipe, int addr); +extern int sc3336p_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC3336P_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336p/sc3336p_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336p/sc3336p_cmos_param.h new file mode 100644 index 00000000..20e82f05 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336p/sc3336p_cmos_param.h @@ -0,0 +1,121 @@ +#ifndef __SC3336P_CMOS_PARAM_H_ +#define __SC3336P_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 "sc3336p_cmos_ex.h" + +static const SC3336P_MODE_S g_astSC3336P_mode[SC3336P_MODE_NUM] = { + [SC3336P_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 sc3336p_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 /* __SC3336P_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336p/sc3336p_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336p/sc3336p_sensor_ctl.c new file mode 100644 index 00000000..0a46c73a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc3336p/sc3336p_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 "sc3336p_cmos_ex.h" + +#define SC3336P_CHIP_ID_HI_ADDR 0x3107 +#define SC3336P_CHIP_ID_LO_ADDR 0x3108 +#define SC3336P_CHIP_ID 0x9c41 + +static void sc3336p_linear_1296P30_init(VI_PIPE ViPipe); + +CVI_U8 sc3336p_i2c_addr = 0x30; /* I2C Address of SC3336P */ +const CVI_U32 sc3336p_addr_byte = 2; +const CVI_U32 sc3336p_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc3336p_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC3336P_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, sc3336p_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 sc3336p_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 sc3336p_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 (sc3336p_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc3336p_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, sc3336p_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc3336p_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 sc3336p_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 (sc3336p_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc3336p_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc3336p_addr_byte + sc3336p_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 sc3336p_standby(VI_PIPE ViPipe) +{ + sc3336p_write_register(ViPipe, 0x0100, 0x00); +} + +void sc3336p_restart(VI_PIPE ViPipe) +{ + sc3336p_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc3336p_write_register(ViPipe, 0x0100, 0x01); +} + +void sc3336p_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC3336P[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + if (g_pastSC3336P[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) { + sc3336p_write_register(ViPipe, + g_pastSC3336P[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC3336P[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } + } +} + +void sc3336p_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; + } + + sc3336p_write_register(ViPipe, 0x3221, val); +} + +int sc3336p_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + delay_ms(4); + if (sc3336p_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = sc3336p_read_register(ViPipe, SC3336P_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 = sc3336p_read_register(ViPipe, SC3336P_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 != SC3336P_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void sc3336p_init(VI_PIPE ViPipe) +{ + sc3336p_i2c_init(ViPipe); + + //linear mode only + sc3336p_linear_1296P30_init(ViPipe); + + g_pastSC3336P[ViPipe]->bInit = CVI_TRUE; +} + +void sc3336p_exit(VI_PIPE ViPipe) +{ + sc3336p_i2c_exit(ViPipe); +} + +/* 1296P30 and 1296P25 */ +static void sc3336p_linear_1296P30_init(VI_PIPE ViPipe) +{ + sc3336p_write_register(ViPipe, 0x0103, 0x01); + sc3336p_write_register(ViPipe, 0x36e9, 0x80); + sc3336p_write_register(ViPipe, 0x37f9, 0x80); + sc3336p_write_register(ViPipe, 0x301f, 0x01); + sc3336p_write_register(ViPipe, 0x30b8, 0x33); + sc3336p_write_register(ViPipe, 0x3253, 0x10); + sc3336p_write_register(ViPipe, 0x325f, 0x20); + sc3336p_write_register(ViPipe, 0x3301, 0x04); + sc3336p_write_register(ViPipe, 0x3306, 0x50); + sc3336p_write_register(ViPipe, 0x3309, 0xf8); + sc3336p_write_register(ViPipe, 0x330a, 0x00); + sc3336p_write_register(ViPipe, 0x330b, 0xd8); + sc3336p_write_register(ViPipe, 0x3314, 0x13); + sc3336p_write_register(ViPipe, 0x331f, 0xe9); + sc3336p_write_register(ViPipe, 0x3333, 0x10); + sc3336p_write_register(ViPipe, 0x3334, 0x40); + sc3336p_write_register(ViPipe, 0x335e, 0x06); + sc3336p_write_register(ViPipe, 0x335f, 0x0a); + sc3336p_write_register(ViPipe, 0x3364, 0x5e); + sc3336p_write_register(ViPipe, 0x337c, 0x02); + sc3336p_write_register(ViPipe, 0x337d, 0x0e); + sc3336p_write_register(ViPipe, 0x3390, 0x01); + sc3336p_write_register(ViPipe, 0x3391, 0x03); + sc3336p_write_register(ViPipe, 0x3392, 0x07); + sc3336p_write_register(ViPipe, 0x3393, 0x04); + sc3336p_write_register(ViPipe, 0x3394, 0x04); + sc3336p_write_register(ViPipe, 0x3395, 0x04); + sc3336p_write_register(ViPipe, 0x3396, 0x08); + sc3336p_write_register(ViPipe, 0x3397, 0x0b); + sc3336p_write_register(ViPipe, 0x3398, 0x1f); + sc3336p_write_register(ViPipe, 0x3399, 0x04); + sc3336p_write_register(ViPipe, 0x339a, 0x0a); + sc3336p_write_register(ViPipe, 0x339b, 0x3a); + sc3336p_write_register(ViPipe, 0x339c, 0x60); + sc3336p_write_register(ViPipe, 0x33a2, 0x04); + sc3336p_write_register(ViPipe, 0x33ac, 0x08); + sc3336p_write_register(ViPipe, 0x33ad, 0x1c); + sc3336p_write_register(ViPipe, 0x33ae, 0x10); + sc3336p_write_register(ViPipe, 0x33af, 0x30); + sc3336p_write_register(ViPipe, 0x33b1, 0x80); + sc3336p_write_register(ViPipe, 0x33b3, 0x48); + sc3336p_write_register(ViPipe, 0x33f9, 0x60); + sc3336p_write_register(ViPipe, 0x33fb, 0x74); + sc3336p_write_register(ViPipe, 0x33fc, 0x4b); + sc3336p_write_register(ViPipe, 0x33fd, 0x5f); + sc3336p_write_register(ViPipe, 0x349f, 0x03); + sc3336p_write_register(ViPipe, 0x34a6, 0x4b); + sc3336p_write_register(ViPipe, 0x34a7, 0x5f); + sc3336p_write_register(ViPipe, 0x34a8, 0x20); + sc3336p_write_register(ViPipe, 0x34a9, 0x18); + sc3336p_write_register(ViPipe, 0x34aa, 0x00); + sc3336p_write_register(ViPipe, 0x34ab, 0xe8); + sc3336p_write_register(ViPipe, 0x34ac, 0x01); + sc3336p_write_register(ViPipe, 0x34ad, 0x00); + sc3336p_write_register(ViPipe, 0x34f8, 0x5f); + sc3336p_write_register(ViPipe, 0x34f9, 0x18); + sc3336p_write_register(ViPipe, 0x3630, 0xc0); + sc3336p_write_register(ViPipe, 0x3631, 0x84); + sc3336p_write_register(ViPipe, 0x3632, 0x64); + sc3336p_write_register(ViPipe, 0x3633, 0x32); + sc3336p_write_register(ViPipe, 0x363b, 0x03); + sc3336p_write_register(ViPipe, 0x363c, 0x08); + sc3336p_write_register(ViPipe, 0x3641, 0x38); + sc3336p_write_register(ViPipe, 0x3670, 0x4e); + sc3336p_write_register(ViPipe, 0x3674, 0xf0); + sc3336p_write_register(ViPipe, 0x3675, 0xc0); + sc3336p_write_register(ViPipe, 0x3676, 0xc0); + sc3336p_write_register(ViPipe, 0x3677, 0x86); + sc3336p_write_register(ViPipe, 0x3678, 0x86); + sc3336p_write_register(ViPipe, 0x3679, 0x86); + sc3336p_write_register(ViPipe, 0x367c, 0x48); + sc3336p_write_register(ViPipe, 0x367d, 0x49); + sc3336p_write_register(ViPipe, 0x367e, 0x4b); + sc3336p_write_register(ViPipe, 0x367f, 0x5f); + sc3336p_write_register(ViPipe, 0x3690, 0x22); + sc3336p_write_register(ViPipe, 0x3691, 0x22); + sc3336p_write_register(ViPipe, 0x3692, 0x33); + sc3336p_write_register(ViPipe, 0x369c, 0x4b); + sc3336p_write_register(ViPipe, 0x369d, 0x4f); + sc3336p_write_register(ViPipe, 0x36b0, 0x87); + sc3336p_write_register(ViPipe, 0x36b1, 0x90); + sc3336p_write_register(ViPipe, 0x36b2, 0xa1); + sc3336p_write_register(ViPipe, 0x36b3, 0xc8); + sc3336p_write_register(ViPipe, 0x36b4, 0x49); + sc3336p_write_register(ViPipe, 0x36b5, 0x4b); + sc3336p_write_register(ViPipe, 0x36b6, 0x4f); + sc3336p_write_register(ViPipe, 0x370f, 0x01); + sc3336p_write_register(ViPipe, 0x3722, 0x09); + sc3336p_write_register(ViPipe, 0x3724, 0x41); + sc3336p_write_register(ViPipe, 0x3725, 0xc1); + sc3336p_write_register(ViPipe, 0x3771, 0x09); + sc3336p_write_register(ViPipe, 0x3772, 0x09); + sc3336p_write_register(ViPipe, 0x3773, 0x05); + sc3336p_write_register(ViPipe, 0x377a, 0x48); + sc3336p_write_register(ViPipe, 0x377b, 0x5f); + sc3336p_write_register(ViPipe, 0x3904, 0x04); + sc3336p_write_register(ViPipe, 0x3905, 0x8c); + sc3336p_write_register(ViPipe, 0x391d, 0x04); + sc3336p_write_register(ViPipe, 0x391f, 0x49); + sc3336p_write_register(ViPipe, 0x3921, 0x20); + sc3336p_write_register(ViPipe, 0x3926, 0x21); + sc3336p_write_register(ViPipe, 0x3933, 0x80); + sc3336p_write_register(ViPipe, 0x3934, 0x08); + sc3336p_write_register(ViPipe, 0x3935, 0x00); + sc3336p_write_register(ViPipe, 0x3936, 0x90); + sc3336p_write_register(ViPipe, 0x3937, 0x78); + sc3336p_write_register(ViPipe, 0x3938, 0x77); + sc3336p_write_register(ViPipe, 0x3939, 0x00); + sc3336p_write_register(ViPipe, 0x393a, 0x00); + sc3336p_write_register(ViPipe, 0x393b, 0x00); + sc3336p_write_register(ViPipe, 0x393c, 0x1c); + sc3336p_write_register(ViPipe, 0x39dc, 0x02); + sc3336p_write_register(ViPipe, 0x3e01, 0x53); + sc3336p_write_register(ViPipe, 0x3e02, 0xe0); + sc3336p_write_register(ViPipe, 0x3e09, 0x00); + sc3336p_write_register(ViPipe, 0x440d, 0x10); + sc3336p_write_register(ViPipe, 0x440e, 0x01); + sc3336p_write_register(ViPipe, 0x4509, 0x20); + sc3336p_write_register(ViPipe, 0x5780, 0x76); + sc3336p_write_register(ViPipe, 0x5784, 0x10); + sc3336p_write_register(ViPipe, 0x5785, 0x04); + sc3336p_write_register(ViPipe, 0x5787, 0x0a); + sc3336p_write_register(ViPipe, 0x5788, 0x0a); + sc3336p_write_register(ViPipe, 0x5789, 0x04); + sc3336p_write_register(ViPipe, 0x578a, 0x0a); + sc3336p_write_register(ViPipe, 0x578b, 0x0a); + sc3336p_write_register(ViPipe, 0x578c, 0x04); + sc3336p_write_register(ViPipe, 0x578d, 0x40); + sc3336p_write_register(ViPipe, 0x5790, 0x08); + sc3336p_write_register(ViPipe, 0x5791, 0x04); + sc3336p_write_register(ViPipe, 0x5792, 0x04); + sc3336p_write_register(ViPipe, 0x5793, 0x08); + sc3336p_write_register(ViPipe, 0x5794, 0x04); + sc3336p_write_register(ViPipe, 0x5795, 0x04); + sc3336p_write_register(ViPipe, 0x5799, 0x46); + sc3336p_write_register(ViPipe, 0x579a, 0x77); + sc3336p_write_register(ViPipe, 0x57a1, 0x04); + sc3336p_write_register(ViPipe, 0x57a8, 0xd2); + sc3336p_write_register(ViPipe, 0x57aa, 0x2a); + sc3336p_write_register(ViPipe, 0x57ab, 0x7f); + sc3336p_write_register(ViPipe, 0x57ac, 0x00); + sc3336p_write_register(ViPipe, 0x57ad, 0x00); + sc3336p_write_register(ViPipe, 0x59e2, 0x08); + sc3336p_write_register(ViPipe, 0x59e3, 0x03); + sc3336p_write_register(ViPipe, 0x59e4, 0x00); + sc3336p_write_register(ViPipe, 0x59e5, 0x10); + sc3336p_write_register(ViPipe, 0x59e6, 0x06); + sc3336p_write_register(ViPipe, 0x59e7, 0x00); + sc3336p_write_register(ViPipe, 0x59e8, 0x08); + sc3336p_write_register(ViPipe, 0x59e9, 0x02); + sc3336p_write_register(ViPipe, 0x59ea, 0x00); + sc3336p_write_register(ViPipe, 0x59eb, 0x10); + sc3336p_write_register(ViPipe, 0x59ec, 0x04); + sc3336p_write_register(ViPipe, 0x59ed, 0x00); + sc3336p_write_register(ViPipe, 0x5ae0, 0xfe); + sc3336p_write_register(ViPipe, 0x5ae1, 0x40); + sc3336p_write_register(ViPipe, 0x5ae2, 0x38); + sc3336p_write_register(ViPipe, 0x5ae3, 0x30); + sc3336p_write_register(ViPipe, 0x5ae4, 0x28); + sc3336p_write_register(ViPipe, 0x5ae5, 0x38); + sc3336p_write_register(ViPipe, 0x5ae6, 0x30); + sc3336p_write_register(ViPipe, 0x5ae7, 0x28); + sc3336p_write_register(ViPipe, 0x5ae8, 0x3f); + sc3336p_write_register(ViPipe, 0x5ae9, 0x34); + sc3336p_write_register(ViPipe, 0x5aea, 0x2c); + sc3336p_write_register(ViPipe, 0x5aeb, 0x3f); + sc3336p_write_register(ViPipe, 0x5aec, 0x34); + sc3336p_write_register(ViPipe, 0x5aed, 0x2c); + sc3336p_write_register(ViPipe, 0x36e9, 0x54); + sc3336p_write_register(ViPipe, 0x37f9, 0x27); + + sc3336p_default_reg_init(ViPipe); + + sc3336p_write_register(ViPipe, 0x0100, 0x01); + + printf("ViPipe:%d,===SC3336P 1296P 30fps 10bit LINE Init OK!===\n", ViPipe); +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc401ai/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc401ai/Makefile new file mode 100644 index 00000000..8a86adab --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc401ai/sc401ai_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc401ai/sc401ai_cmos.c new file mode 100644 index 00000000..7f19a552 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc401ai/sc401ai_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc401ai/sc401ai_cmos_ex.h new file mode 100644 index 00000000..c7c3d333 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc401ai/sc401ai_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc401ai/sc401ai_cmos_param.h new file mode 100644 index 00000000..a5603f35 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc401ai/sc401ai_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc401ai/sc401ai_sensor_ctl.c new file mode 100644 index 00000000..d13239be --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336/Makefile new file mode 100644 index 00000000..3190f8c0 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336/sc4336_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336/sc4336_cmos.c new file mode 100644 index 00000000..82b411b6 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336/sc4336_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336/sc4336_cmos_ex.h new file mode 100644 index 00000000..fdf3ae46 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336/sc4336_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336/sc4336_cmos_param.h new file mode 100644 index 00000000..84fb617d --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336/sc4336_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336/sc4336_sensor_ctl.c new file mode 100644 index 00000000..838a363a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336p/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336p/Makefile new file mode 100644 index 00000000..f2679b71 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336p/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_sc4336p.a +TARGET_SO = $(MW_LIB)/libsns_sc4336p.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336p/sc4336p_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336p/sc4336p_cmos.c new file mode 100644 index 00000000..1901daec --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336p/sc4336p_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 "sc4336p_cmos_ex.h" +#include "sc4336p_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 SC4336P_ID 4336 +#define SENSOR_SC4336P_WIDTH 2560 +#define SENSOR_SC4336P_HEIGHT 1440 +#define SC4336P_I2C_ADDR_1 0x30 +#define SC4336P_I2C_ADDR_2 0x32 +#define SC4336P_I2C_ADDR_IS_VALID(addr) ((addr) == SC4336P_I2C_ADDR_1 || (addr) == SC4336P_I2C_ADDR_2) + +#define SC4336P_EXPACCURACY (1) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC4336P[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC4336P_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC4336P[dev]) +#define SC4336P_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC4336P[dev] = pstCtx) +#define SC4336P_SENSOR_RESET_CTX(dev) (g_pastSC4336P[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC4336P_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC4336P_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC4336P_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +ISP_SNS_MIRRORFLIP_TYPE_E g_aeSc4336p_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); +/*****SC4336P Lines Range*****/ +#define SC4336P_FULL_LINES_MAX (0x7FFF) + +/*****SC4336P Register Address*****/ +#define SC4336P_EXP_ADDR 0x3E00 +#define SC4336P_AGAIN_ADDR 0x3E09 +#define SC4336P_DGAIN_ADDR 0x3E06 +#define SC4336P_VMAX_ADDR 0x320E + +#define SC4336P_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); + SC4336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC4336P_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = SC4336P_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_astSC4336P_mode[pstSnsState->u8ImgMode].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astSC4336P_mode[pstSnsState->u8ImgMode].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = g_astSC4336P_mode[pstSnsState->u8ImgMode].stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = g_astSC4336P_mode[pstSnsState->u8ImgMode].stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = g_astSC4336P_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = g_astSC4336P_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_astSC4336P_mode[pstSnsState->u8ImgMode].stExp[0].u32Max; + pstAeSnsDft->u32MinIntTime = g_astSC4336P_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); + SC4336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astSC4336P_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC4336P_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC4336P_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC4336P_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 > SC4336P_FULL_LINES_MAX) ? SC4336P_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; + + SC4336P_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; + + SC4336P_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 SC4336P_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC4336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astSC4336P_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; + + SC4336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = SC4336P_MODE_1440P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC4336P_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); + SC4336P_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_aunSC4336P_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 = sc4336p_i2c_addr; + pstI2c_data[i].u32AddrByteNum = sc4336p_addr_byte; + pstI2c_data[i].u32DataByteNum = sc4336p_data_byte; + } + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC4336P_EXP_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC4336P_EXP_ADDR + 1; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC4336P_EXP_ADDR + 2; + + pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = SC4336P_AGAIN_ADDR; + pstI2c_data[LINEAR_DGAIN_ADDR].u32RegAddr = SC4336P_DGAIN_ADDR; + pstI2c_data[LINEAR_D_FINEGAIN_ADDR].u32RegAddr = SC4336P_DGAIN_ADDR + 1; + + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC4336P_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC4336P_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); + SC4336P_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 (SC4336P_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC4336P_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; + + SC4336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + if (pstSnsState->bInit == CVI_TRUE && g_aeSc4336p_MirrorFip[ViPipe] != eSnsMirrorFlip) { + sc4336p_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeSc4336p_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const SC4336P_MODE_S *pstMode = CVI_NULL; + + SC4336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = SC4336P_MODE_1440P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC4336P_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; + + SC4336P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &sc4336p_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC4336P_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC4336P_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 = &sc4336p_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 = sc4336p_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = sc4336p_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 (SC4336P_I2C_ADDR_IS_VALID(s32I2cAddr)) + sc4336p_i2c_addr = s32I2cAddr; +} + +static CVI_S32 sc4336p_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC4336P_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC4336P_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)); + + SC4336P_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + SC4336P_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC4336P_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 = SC4336P_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, SC4336P_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, SC4336P_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, SC4336P_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_au16SC4336P_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC4336P_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC4336P_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = sc4336p_standby, + .pfnRestart = sc4336p_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = sc4336p_write_register, + .pfnReadReg = sc4336p_read_register, + .pfnSetBusInfo = sc4336p_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 = sc4336p_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336p/sc4336p_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336p/sc4336p_cmos_ex.h new file mode 100644 index 00000000..d09e26b5 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336p/sc4336p_cmos_ex.h @@ -0,0 +1,78 @@ +#ifndef __SC4336P_CMOS_EX_H_ +#define __SC4336P_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 sc4336p_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 _SC4336P_MODE_E { + SC4336P_MODE_1440P30 = 0, + SC4336P_MODE_NUM +} SC4336P_MODE_E; + +typedef struct _SC4336P_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]; +} SC4336P_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC4336P[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC4336P_BusInfo[]; +extern CVI_U16 g_au16SC4336P_GainMode[]; +extern CVI_U16 g_au16SC4336P_L2SMode[]; +extern CVI_U8 sc4336p_i2c_addr; +extern const CVI_U32 sc4336p_addr_byte; +extern const CVI_U32 sc4336p_data_byte; +extern void sc4336p_init(VI_PIPE ViPipe); +extern void sc4336p_exit(VI_PIPE ViPipe); +extern void sc4336p_standby(VI_PIPE ViPipe); +extern void sc4336p_restart(VI_PIPE ViPipe); +extern int sc4336p_write_register(VI_PIPE ViPipe, int addr, int data); +extern int sc4336p_read_register(VI_PIPE ViPipe, int addr); +extern void sc4336p_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int sc4336p_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC4336P_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336p/sc4336p_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336p/sc4336p_cmos_param.h new file mode 100644 index 00000000..d086f8ae --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336p/sc4336p_cmos_param.h @@ -0,0 +1,121 @@ +#ifndef __SC4336P_CMOS_PARAM_H_ +#define __SC4336P_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 "sc4336p_cmos_ex.h" + +static const SC4336P_MODE_S g_astSC4336P_mode[SC4336P_MODE_NUM] = { + [SC4336P_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 = 16182, + .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 sc4336p_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 /* __SC4336P_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336p/sc4336p_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336p/sc4336p_sensor_ctl.c new file mode 100644 index 00000000..fccedf9d --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc4336p/sc4336p_sensor_ctl.c @@ -0,0 +1,384 @@ +#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 "sc4336p_cmos_ex.h" + +static void sc4336p_linear_1440p30_init(VI_PIPE ViPipe); + +CVI_U8 sc4336p_i2c_addr = 0x30; /* I2C Address of SC4336P */ +const CVI_U32 sc4336p_addr_byte = 2; +const CVI_U32 sc4336p_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int sc4336p_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunSC4336P_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, sc4336p_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 sc4336p_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 sc4336p_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 (sc4336p_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, sc4336p_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, sc4336p_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (sc4336p_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 sc4336p_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 (sc4336p_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (sc4336p_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, sc4336p_addr_byte + sc4336p_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 sc4336p_standby(VI_PIPE ViPipe) +{ + sc4336p_write_register(ViPipe, 0x0100, 0x00); +} + +void sc4336p_restart(VI_PIPE ViPipe) +{ + sc4336p_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + sc4336p_write_register(ViPipe, 0x0100, 0x01); +} + +void sc4336p_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC4336P[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + sc4336p_write_register(ViPipe, + g_pastSC4336P[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC4336P[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +void sc4336p_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; + } + + sc4336p_write_register(ViPipe, 0x3221, val); +} + +#define SC4336P_CHIP_ID_HI_ADDR 0x3107 +#define SC4336P_CHIP_ID_LO_ADDR 0x3108 +#define SC4336P_CHIP_ID 0x9c42 + +int sc4336p_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + if (sc4336p_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + delay_ms(5); + + nVal = sc4336p_read_register(ViPipe, SC4336P_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 = sc4336p_read_register(ViPipe, SC4336P_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 != SC4336P_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + printf("%d\n", ViPipe); + return CVI_SUCCESS; +} + + +void sc4336p_init(VI_PIPE ViPipe) +{ + sc4336p_i2c_init(ViPipe); + + sc4336p_linear_1440p30_init(ViPipe); + + g_pastSC4336P[ViPipe]->bInit = CVI_TRUE; +} + +void sc4336p_exit(VI_PIPE ViPipe) +{ + sc4336p_i2c_exit(ViPipe); +} + +/* 1440P30 and 1440P25 */ +static void sc4336p_linear_1440p30_init(VI_PIPE ViPipe) +{ + sc4336p_write_register(ViPipe, 0x0103, 0x01); + sc4336p_write_register(ViPipe, 0x36e9, 0x80); + sc4336p_write_register(ViPipe, 0x37f9, 0x80); + sc4336p_write_register(ViPipe, 0x301f, 0x01); + sc4336p_write_register(ViPipe, 0x30b8, 0x44); + sc4336p_write_register(ViPipe, 0x3253, 0x10); + sc4336p_write_register(ViPipe, 0x3301, 0x0a); + sc4336p_write_register(ViPipe, 0x3302, 0xff); + sc4336p_write_register(ViPipe, 0x3305, 0x00); + sc4336p_write_register(ViPipe, 0x3306, 0x90); + sc4336p_write_register(ViPipe, 0x3308, 0x08); + sc4336p_write_register(ViPipe, 0x330a, 0x01); + sc4336p_write_register(ViPipe, 0x330b, 0xb0); + sc4336p_write_register(ViPipe, 0x330d, 0xf0); + sc4336p_write_register(ViPipe, 0x3314, 0x14); + sc4336p_write_register(ViPipe, 0x3333, 0x10); + sc4336p_write_register(ViPipe, 0x3334, 0x40); + sc4336p_write_register(ViPipe, 0x335e, 0x06); + sc4336p_write_register(ViPipe, 0x335f, 0x0a); + sc4336p_write_register(ViPipe, 0x3364, 0x5e); + sc4336p_write_register(ViPipe, 0x337d, 0x0e); + sc4336p_write_register(ViPipe, 0x338f, 0x20); + sc4336p_write_register(ViPipe, 0x3390, 0x08); + sc4336p_write_register(ViPipe, 0x3391, 0x09); + sc4336p_write_register(ViPipe, 0x3392, 0x0f); + sc4336p_write_register(ViPipe, 0x3393, 0x18); + sc4336p_write_register(ViPipe, 0x3394, 0x60); + sc4336p_write_register(ViPipe, 0x3395, 0xff); + sc4336p_write_register(ViPipe, 0x3396, 0x08); + sc4336p_write_register(ViPipe, 0x3397, 0x09); + sc4336p_write_register(ViPipe, 0x3398, 0x0f); + sc4336p_write_register(ViPipe, 0x3399, 0x0a); + sc4336p_write_register(ViPipe, 0x339a, 0x18); + sc4336p_write_register(ViPipe, 0x339b, 0x60); + sc4336p_write_register(ViPipe, 0x339c, 0xff); + sc4336p_write_register(ViPipe, 0x33a2, 0x04); + sc4336p_write_register(ViPipe, 0x33ad, 0x0c); + sc4336p_write_register(ViPipe, 0x33b2, 0x40); + sc4336p_write_register(ViPipe, 0x33b3, 0x30); + sc4336p_write_register(ViPipe, 0x33f8, 0x00); + sc4336p_write_register(ViPipe, 0x33f9, 0xb0); + sc4336p_write_register(ViPipe, 0x33fa, 0x00); + sc4336p_write_register(ViPipe, 0x33fb, 0xf8); + sc4336p_write_register(ViPipe, 0x33fc, 0x09); + sc4336p_write_register(ViPipe, 0x33fd, 0x1f); + sc4336p_write_register(ViPipe, 0x349f, 0x03); + sc4336p_write_register(ViPipe, 0x34a6, 0x09); + sc4336p_write_register(ViPipe, 0x34a7, 0x1f); + sc4336p_write_register(ViPipe, 0x34a8, 0x28); + sc4336p_write_register(ViPipe, 0x34a9, 0x28); + sc4336p_write_register(ViPipe, 0x34aa, 0x01); + sc4336p_write_register(ViPipe, 0x34ab, 0xe0); + sc4336p_write_register(ViPipe, 0x34ac, 0x02); + sc4336p_write_register(ViPipe, 0x34ad, 0x28); + sc4336p_write_register(ViPipe, 0x34f8, 0x1f); + sc4336p_write_register(ViPipe, 0x34f9, 0x20); + sc4336p_write_register(ViPipe, 0x3630, 0xc0); + sc4336p_write_register(ViPipe, 0x3631, 0x84); + sc4336p_write_register(ViPipe, 0x3632, 0x54); + sc4336p_write_register(ViPipe, 0x3633, 0x44); + sc4336p_write_register(ViPipe, 0x3637, 0x49); + sc4336p_write_register(ViPipe, 0x363f, 0xc0); + sc4336p_write_register(ViPipe, 0x3641, 0x28); + sc4336p_write_register(ViPipe, 0x3670, 0x56); + sc4336p_write_register(ViPipe, 0x3674, 0xb0); + sc4336p_write_register(ViPipe, 0x3675, 0xa0); + sc4336p_write_register(ViPipe, 0x3676, 0xa0); + sc4336p_write_register(ViPipe, 0x3677, 0x84); + sc4336p_write_register(ViPipe, 0x3678, 0x88); + sc4336p_write_register(ViPipe, 0x3679, 0x8d); + sc4336p_write_register(ViPipe, 0x367c, 0x09); + sc4336p_write_register(ViPipe, 0x367d, 0x0b); + sc4336p_write_register(ViPipe, 0x367e, 0x08); + sc4336p_write_register(ViPipe, 0x367f, 0x0f); + sc4336p_write_register(ViPipe, 0x3696, 0x24); + sc4336p_write_register(ViPipe, 0x3697, 0x34); + sc4336p_write_register(ViPipe, 0x3698, 0x34); + sc4336p_write_register(ViPipe, 0x36a0, 0x0f); + sc4336p_write_register(ViPipe, 0x36a1, 0x1f); + sc4336p_write_register(ViPipe, 0x36b0, 0x81); + sc4336p_write_register(ViPipe, 0x36b1, 0x83); + sc4336p_write_register(ViPipe, 0x36b2, 0x85); + sc4336p_write_register(ViPipe, 0x36b3, 0x8b); + sc4336p_write_register(ViPipe, 0x36b4, 0x09); + sc4336p_write_register(ViPipe, 0x36b5, 0x0b); + sc4336p_write_register(ViPipe, 0x36b6, 0x0f); + sc4336p_write_register(ViPipe, 0x370f, 0x01); + sc4336p_write_register(ViPipe, 0x3722, 0x09); + sc4336p_write_register(ViPipe, 0x3724, 0x21); + sc4336p_write_register(ViPipe, 0x3771, 0x09); + sc4336p_write_register(ViPipe, 0x3772, 0x05); + sc4336p_write_register(ViPipe, 0x3773, 0x05); + sc4336p_write_register(ViPipe, 0x377a, 0x0f); + sc4336p_write_register(ViPipe, 0x377b, 0x1f); + sc4336p_write_register(ViPipe, 0x3905, 0x8c); + sc4336p_write_register(ViPipe, 0x391d, 0x02); + sc4336p_write_register(ViPipe, 0x391f, 0x49); + sc4336p_write_register(ViPipe, 0x3926, 0x21); + sc4336p_write_register(ViPipe, 0x3933, 0x80); + sc4336p_write_register(ViPipe, 0x3934, 0x03); + sc4336p_write_register(ViPipe, 0x3937, 0x7b); + sc4336p_write_register(ViPipe, 0x3939, 0x00); + sc4336p_write_register(ViPipe, 0x393a, 0x00); + sc4336p_write_register(ViPipe, 0x39dc, 0x02); + sc4336p_write_register(ViPipe, 0x3e00, 0x00); + sc4336p_write_register(ViPipe, 0x3e01, 0x5d); + sc4336p_write_register(ViPipe, 0x3e02, 0x40); + sc4336p_write_register(ViPipe, 0x440e, 0x02); + sc4336p_write_register(ViPipe, 0x4509, 0x28); + sc4336p_write_register(ViPipe, 0x450d, 0x32); + sc4336p_write_register(ViPipe, 0x5000, 0x06); + sc4336p_write_register(ViPipe, 0x578d, 0x40); + sc4336p_write_register(ViPipe, 0x5799, 0x46); + sc4336p_write_register(ViPipe, 0x579a, 0x77); + sc4336p_write_register(ViPipe, 0x57d9, 0x46); + sc4336p_write_register(ViPipe, 0x57da, 0x77); + sc4336p_write_register(ViPipe, 0x5ae0, 0xfe); + sc4336p_write_register(ViPipe, 0x5ae1, 0x40); + sc4336p_write_register(ViPipe, 0x5ae2, 0x38); + sc4336p_write_register(ViPipe, 0x5ae3, 0x30); + sc4336p_write_register(ViPipe, 0x5ae4, 0x28); + sc4336p_write_register(ViPipe, 0x5ae5, 0x38); + sc4336p_write_register(ViPipe, 0x5ae6, 0x30); + sc4336p_write_register(ViPipe, 0x5ae7, 0x28); + sc4336p_write_register(ViPipe, 0x5ae8, 0x3f); + sc4336p_write_register(ViPipe, 0x5ae9, 0x34); + sc4336p_write_register(ViPipe, 0x5aea, 0x2c); + sc4336p_write_register(ViPipe, 0x5aeb, 0x3f); + sc4336p_write_register(ViPipe, 0x5aec, 0x34); + sc4336p_write_register(ViPipe, 0x5aed, 0x2c); + sc4336p_write_register(ViPipe, 0x36e9, 0x44); + sc4336p_write_register(ViPipe, 0x37f9, 0x44); + + sc4336p_default_reg_init(ViPipe); + + sc4336p_write_register(ViPipe, 0x0100, 0x01); + + delay_ms(100); + + printf("ViPipe:%d,===SC4336P 1440P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc500ai/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc500ai/Makefile new file mode 100644 index 00000000..99772447 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc500ai/sc500ai_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc500ai/sc500ai_cmos.c new file mode 100644 index 00000000..fc48cd40 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc500ai/sc500ai_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc500ai/sc500ai_cmos_ex.h new file mode 100644 index 00000000..7438fd9c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc500ai/sc500ai_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc500ai/sc500ai_cmos_param.h new file mode 100644 index 00000000..794712a2 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc500ai/sc500ai_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc500ai/sc500ai_sensor_ctl.c new file mode 100644 index 00000000..cd783e39 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc501ai_2L/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc501ai_2L/Makefile new file mode 100644 index 00000000..1bb770b2 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc501ai_2L/sc501ai_2L_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc501ai_2L/sc501ai_2L_cmos.c new file mode 100644 index 00000000..dfc19fa4 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc501ai_2L/sc501ai_2L_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc501ai_2L/sc501ai_2L_cmos_ex.h new file mode 100644 index 00000000..57cb54b6 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc501ai_2L/sc501ai_2L_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc501ai_2L/sc501ai_2L_cmos_param.h new file mode 100644 index 00000000..1527a6fc --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc501ai_2L/sc501ai_2L_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc501ai_2L/sc501ai_2L_sensor_ctl.c new file mode 100644 index 00000000..fc7a232c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc531ai_2L/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc531ai_2L/Makefile new file mode 100644 index 00000000..ae828df6 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc531ai_2L/sc531ai_2L_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc531ai_2L/sc531ai_2L_cmos.c new file mode 100644 index 00000000..550c1a30 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc531ai_2L/sc531ai_2L_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc531ai_2L/sc531ai_2L_cmos_ex.h new file mode 100644 index 00000000..05c948c7 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc531ai_2L/sc531ai_2L_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc531ai_2L/sc531ai_2L_cmos_param.h new file mode 100644 index 00000000..ec0de0eb --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc531ai_2L/sc531ai_2L_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc531ai_2L/sc531ai_2L_sensor_ctl.c new file mode 100644 index 00000000..d005dc75 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc5336_2L/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc5336_2L/Makefile new file mode 100644 index 00000000..a4b7ecc7 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc5336_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_sc5336_2L.a +TARGET_SO = $(MW_LIB)/libsns_sc5336_2L.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc5336_2L/sc5336_2L_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc5336_2L/sc5336_2L_cmos.c new file mode 100644 index 00000000..c9667871 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc5336_2L/sc5336_2L_cmos.c @@ -0,0 +1,1104 @@ +#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 "sc5336_2L_cmos_ex.h" +#include "sc5336_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 SC5336_2L_ID 500 +#define SENSOR_SC5336_2L_WIDTH 2880 +#define SENSOR_SC5336_2L_HEIGHT 1620 +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastSC5336_2L[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define SC5336_2L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC5336_2L[dev]) +#define SC5336_2L_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC5336_2L[dev] = pstCtx) +#define SC5336_2L_SENSOR_RESET_CTX(dev) (g_pastSC5336_2L[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunSC5336_2L_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16SC5336_2L_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16SC5336_2L_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +SC5336_2L_STATE_S g_astSC5336_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); +/*****SC5336_2L Lines Range*****/ +#define SC5336_2L_FULL_LINES_MAX (0x7FFF) + +/*****SC5336_2L Register Address*****/ +#define SC5336_2L_SHS1_0_ADDR 0x3E00 +#define SC5336_2L_SHS1_1_ADDR 0x3E01 +#define SC5336_2L_SHS1_2_ADDR 0x3E02 +#define SC5336_2L_AGAIN_0_ADDR 0x3E09 +#define SC5336_2L_DGAIN_0_ADDR 0x3E06 +#define SC5336_2L_VMAX_ADDR 0x320E +#define SC5336_2L_TABLE_END 0xFFFF + +#define SC5336_2L_RES_IS_1620P(w, h) ((w) <= 2880 && (h) <= 1620) +#define SC5336_2L_RES_IS_1618P(w, h) ((w) == 2880 && (h) == 1618) + +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); + SC5336_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + if (0x00 == SC5336_2l_read_register(ViPipe, 0x3040)) { + pstSnsState->u8ImgMode = SC5336_2L_MODE_1618P30; + } else if (0x03 == SC5336_2l_read_register(ViPipe, 0x3040)) { + pstSnsState->u8ImgMode = SC5336_2L_MODE_1620P30; + } + +#if 0 + memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S)); +#endif + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = SC5336_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 = 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_astSC5336_2L_mode[pstSnsState->u8ImgMode].f32MaxFps; + pstAeSnsDft->f32MinFps = g_astSC5336_2L_mode[pstSnsState->u8ImgMode].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = g_astSC5336_2L_mode[pstSnsState->u8ImgMode].stAgain[0].u32Max; + pstAeSnsDft->u32MinAgain = g_astSC5336_2L_mode[pstSnsState->u8ImgMode].stAgain[0].u32Min; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = g_astSC5336_2L_mode[pstSnsState->u8ImgMode].stDgain[0].u32Max; + pstAeSnsDft->u32MinDgain = g_astSC5336_2L_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 = pstSnsState->u32FLStd - 4; + 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); + SC5336_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + if (0x00 == SC5336_2l_read_register(ViPipe, 0x3040)) { + pstSnsState->u8ImgMode = SC5336_2L_MODE_1618P30; + } else if (0x03 == SC5336_2l_read_register(ViPipe, 0x3040)) { + pstSnsState->u8ImgMode = SC5336_2L_MODE_1620P30; + } + + u32Vts = g_astSC5336_2L_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astSC5336_2L_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astSC5336_2L_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case SC5336_2L_MODE_1620P30: + case SC5336_2L_MODE_1618P30: + 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 > SC5336_2L_FULL_LINES_MAX) ? SC5336_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 = pstSnsState->u32FLStd - 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; + + SC5336_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 = pstSnsState->au32FL[0] - 4; + + /* linear exposure reg range: + * min : 2 + * max : vts - 4 + * step : 1 + */ + u32TmpIntTime = (u32TmpIntTime > maxExp) ? maxExp : u32TmpIntTime; + if (u32TmpIntTime < 2) + u32TmpIntTime = 2; + 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[] = { + { + .gainMax = 2016, + .idxBase = 0, + .regGain = 0x00, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 4032, + .idxBase = 32, + .regGain = 0x08, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 8064, + .idxBase = 64, + .regGain = 0x09, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 16128, + .idxBase = 96, + .regGain = 0x0b, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 32256, + .idxBase = 128, + .regGain = 0x0F, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, + { + .gainMax = 32768, + .idxBase = 160, + .regGain = 0x1F, + .regGainFineBase = 0x80, + .regGainFineStep = 4, + }, +}; + +static CVI_U32 Again_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, 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, + + 32768, +}; + +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, 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, 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, +}; + +CVI_U32 AtableSize = sizeof(Again_table) / sizeof(CVI_U32); +CVI_U32 DtableSize = 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[AtableSize - 1]) { + *pu32AgainLin = Again_table[AtableSize - 1]; + *pu32AgainDb = AtableSize - 1; + return CVI_SUCCESS; + } + + for (i = 1; i < AtableSize; 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[DtableSize - 1]) { + *pu32DgainLin = Dgain_table[DtableSize - 1]; + *pu32DgainDb = DtableSize - 1; + return CVI_SUCCESS; + } + + for (i = 1; i < DtableSize; 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; + + SC5336_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. */ + 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); + } + + 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_astSC5336_2L_State[ViPipe].u32Sexp_MAX - 14; + + (void) u16ManRatioEnable; + + CMOS_CHECK_POINTER(au32Ratio); + CMOS_CHECK_POINTER(au32IntTimeMax); + CMOS_CHECK_POINTER(au32IntTimeMin); + CMOS_CHECK_POINTER(pu32LFMaxIntTime); + SC5336_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 SC5336_2L_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + SC5336_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + if (0x00 == SC5336_2l_read_register(ViPipe, 0x3040)) { + pstSnsState->u8ImgMode = SC5336_2L_MODE_1618P30; + } else if (0x03 == SC5336_2l_read_register(ViPipe, 0x3040)) { + pstSnsState->u8ImgMode = SC5336_2L_MODE_1620P30; + } + + pstMode = &g_astSC5336_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; + + SC5336_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + if (0x00 == SC5336_2l_read_register(ViPipe, 0x3040)) { + pstSnsState->u8ImgMode = SC5336_2L_MODE_1618P30; + } else if (0x03 == SC5336_2l_read_register(ViPipe, 0x3040)) { + pstSnsState->u8ImgMode = SC5336_2L_MODE_1620P30; + } + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astSC5336_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); + SC5336_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_aunSC5336_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 = SC5336_2l_i2c_addr; + pstI2c_data[i].u32AddrByteNum = SC5336_2l_addr_byte; + pstI2c_data[i].u32DataByteNum = SC5336_2l_data_byte; + } + + //Linear Mode Regs + pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC5336_2L_SHS1_0_ADDR; + pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC5336_2L_SHS1_1_ADDR; + pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC5336_2L_SHS1_2_ADDR; + pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC5336_2L_AGAIN_0_ADDR; + pstI2c_data[LINEAR_AGAIN_1_ADDR].u32RegAddr = SC5336_2L_DGAIN_0_ADDR + 1; + pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC5336_2L_DGAIN_0_ADDR; + pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC5336_2L_DGAIN_0_ADDR + 1; + pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC5336_2L_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC5336_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); + SC5336_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 (SC5336_2L_RES_IS_1618P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC5336_2L_MODE_1618P30; + } else if (SC5336_2L_RES_IS_1620P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = SC5336_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 SC5336_2L_MODE_S *pstMode = CVI_NULL; + + SC5336_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + + if (0x00 == SC5336_2l_read_register(ViPipe, 0x3040)) { + pstSnsState->u8ImgMode = SC5336_2L_MODE_1618P30; + } else if (0x03 == SC5336_2l_read_register(ViPipe, 0x3040)) { + pstSnsState->u8ImgMode = SC5336_2L_MODE_1620P30; + } + + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astSC5336_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; + + SC5336_2L_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + if (0x00 == SC5336_2l_read_register(ViPipe, 0x3040)) { + pstSnsState->u8ImgMode = SC5336_2L_MODE_1618P30; + } else if (0x03 == SC5336_2l_read_register(ViPipe, 0x3040)) { + pstSnsState->u8ImgMode = SC5336_2L_MODE_1620P30; + } + + memcpy(pstRxAttr, &SC5336_2l_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astSC5336_2L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astSC5336_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 = &SC5336_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 = SC5336_2l_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = SC5336_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 SC5336_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunSC5336_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; + + SC5336_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)); + + SC5336_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; + + SC5336_2L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + SC5336_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 = SC5336_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, SC5336_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, SC5336_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, SC5336_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_au16SC5336_2L_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16SC5336_2L_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsSC5336_2L_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = SC5336_2l_standby, + .pfnRestart = SC5336_2l_restart, + .pfnMirrorFlip = SC5336_2l_mirror_flip, + .pfnWriteReg = SC5336_2l_write_register, + .pfnReadReg = SC5336_2l_read_register, + .pfnSetBusInfo = SC5336_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 = SC5336_2l_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc5336_2L/sc5336_2L_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc5336_2L/sc5336_2L_cmos_ex.h new file mode 100644 index 00000000..3f3c2616 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc5336_2L/sc5336_2L_cmos_ex.h @@ -0,0 +1,86 @@ +#ifndef __SC5336_2L_CMOS_EX_H_ +#define __SC5336_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 SC5336_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 _SC5336_2L_MODE_E { + SC5336_2L_MODE_1620P30 = 0, + SC5336_2L_MODE_1618P30 = 1, + SC5336_2L_MODE_LINEAR_NUM, + SC5336_2L_MODE_NUM +} SC5336_2L_MODE_E; + +typedef struct _SC5336_2L_STATE_S { + CVI_U32 u32Sexp_MAX; /* (2*{16’h3e23,16’h3e24} – 'd10)/2 */ +} SC5336_2L_STATE_S; + +typedef struct _SC5336_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]; +} SC5336_2L_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastSC5336_2L[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunSC5336_2L_BusInfo[]; +extern CVI_U16 g_au16SC5336_2L_GainMode[]; +extern CVI_U16 g_au16SC5336_2L_L2SMode[]; +extern const CVI_U8 SC5336_2l_i2c_addr; +extern const CVI_U32 SC5336_2l_addr_byte; +extern const CVI_U32 SC5336_2l_data_byte; +extern void SC5336_2l_init(VI_PIPE ViPipe); +extern void SC5336_2l_exit(VI_PIPE ViPipe); +extern void SC5336_2l_standby(VI_PIPE ViPipe); +extern void SC5336_2l_restart(VI_PIPE ViPipe); +extern int SC5336_2l_write_register(VI_PIPE ViPipe, int addr, int data); +extern int SC5336_2l_read_register(VI_PIPE ViPipe, int addr); +extern void SC5336_2l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int SC5336_2l_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC5336_2L_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc5336_2L/sc5336_2L_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc5336_2L/sc5336_2L_cmos_param.h new file mode 100644 index 00000000..2bc3cd8d --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc5336_2L/sc5336_2L_cmos_param.h @@ -0,0 +1,267 @@ +#ifndef __SC5336_2L_CMOS_PARAM_H_ +#define __SC5336_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 "sc5336_2L_cmos_ex.h" + +static const SC5336_2L_MODE_S g_astSC5336_2L_mode[SC5336_2L_MODE_NUM] = { + [SC5336_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.65, /* 1800 * 30 / 0x7FFF*/ + .u32HtsDef = 2560, /* NA */ + .u32VtsDef = 1800, + .stExp[0] = { + .u16Min = 2, + .u16Max = 1796,/* vts-4 */ + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 32768, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16128, + .u32Def = 1024, + .u32Step = 1, + }, + }, + [SC5336_2L_MODE_1618P30] = { + .name = "1618p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2880, + .u32Height = 1618, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2880, + .u32Height = 1618, + }, + .stMaxSize = { + .u32Width = 2880, + .u32Height = 1618, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 1.65, /* 1800 * 30 / 0x7FFF*/ + .u32HtsDef = 2560, /* NA */ + .u32VtsDef = 1800, + .stExp[0] = { + .u16Min = 2, + .u16Max = 1796,/* vts-4 */ + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 1024, + .u32Max = 32768, + .u32Def = 1024, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 1024, + .u32Max = 16128, + .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 = {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 SC5336_2l_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 = {0, 0, 0, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_VC, + .dphy = { + .enable = 1, + .hs_settle = 10, + }, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_27M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __SC5336_2L_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc5336_2L/sc5336_2L_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc5336_2L/sc5336_2L_sensor_ctl.c new file mode 100644 index 00000000..3f982624 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sms_sc5336_2L/sc5336_2L_sensor_ctl.c @@ -0,0 +1,483 @@ +#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 "sc5336_2L_cmos_ex.h" + +static void SC5336_2l_linear_1620p30_init(VI_PIPE ViPipe); + +const CVI_U8 SC5336_2l_i2c_addr = 0x30; /* I2C Address of SC5336_2L */ +const CVI_U32 SC5336_2l_addr_byte = 2; +const CVI_U32 SC5336_2l_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int SC5336_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_aunSC5336_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, SC5336_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 SC5336_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 SC5336_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 (SC5336_2l_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, SC5336_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, SC5336_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 (SC5336_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 SC5336_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 (SC5336_2l_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + + if (SC5336_2l_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, SC5336_2l_addr_byte + SC5336_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 SC5336_2l_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) + SC5336_2l_write_register(ViPipe, addr, data); + } +} + +void SC5336_2l_standby(VI_PIPE ViPipe) +{ + SC5336_2l_write_register(ViPipe, 0x0100, 0x00); +} + +void SC5336_2l_restart(VI_PIPE ViPipe) +{ + SC5336_2l_write_register(ViPipe, 0x0100, 0x00); + delay_ms(20); + SC5336_2l_write_register(ViPipe, 0x0100, 0x01); +} + +void SC5336_2l_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastSC5336_2L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + SC5336_2l_write_register(ViPipe, + g_pastSC5336_2L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastSC5336_2L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define SC5336_2L_CHIP_ID_HI_ADDR 0x3107 +#define SC5336_2L_CHIP_ID_LO_ADDR 0x3108 +#define SC5336_2L_CHIP_ID 0xce50 + +void SC5336_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; + } + + SC5336_2l_write_register(ViPipe, 0x3221, val); +} + +int SC5336_2l_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (SC5336_2l_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = SC5336_2l_read_register(ViPipe, SC5336_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 = SC5336_2l_read_register(ViPipe, SC5336_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 != SC5336_2L_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void SC5336_2l_init(VI_PIPE ViPipe) +{ + WDR_MODE_E enWDRMode; + CVI_BOOL bInit; + + bInit = g_pastSC5336_2L[ViPipe]->bInit; + enWDRMode = g_pastSC5336_2L[ViPipe]->enWDRMode; + + SC5336_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 { + SC5336_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 { + SC5336_2l_linear_1620p30_init(ViPipe); + } + } + g_pastSC5336_2L[ViPipe]->bInit = CVI_TRUE; +} + +void SC5336_2l_exit(VI_PIPE ViPipe) +{ + SC5336_2l_i2c_exit(ViPipe); +} + +/* 1620P30 and 1620P25 */ +static void SC5336_2l_linear_1620p30_init(VI_PIPE ViPipe) +{ + SC5336_2l_write_register(ViPipe, 0x0103, 0x01); + SC5336_2l_write_register(ViPipe, 0x36e9, 0x80); + SC5336_2l_write_register(ViPipe, 0x37f9, 0x80); + + if (0x00 == SC5336_2l_read_register(ViPipe, 0x3040)) { + // 2880 * 1618 + SC5336_2l_write_register(ViPipe, 0x301f, 0x03); + SC5336_2l_write_register(ViPipe, 0x3207, 0x5b); + SC5336_2l_write_register(ViPipe, 0x320b, 0x52); + } else if (0x03 == SC5336_2l_read_register(ViPipe, 0x3040)) { + // 2880 * 1620 + SC5336_2l_write_register(ViPipe, 0x301f, 0x01); + } + + SC5336_2l_write_register(ViPipe, 0x320e, 0x07); + SC5336_2l_write_register(ViPipe, 0x320f, 0x08); + SC5336_2l_write_register(ViPipe, 0x3213, 0x04); + SC5336_2l_write_register(ViPipe, 0x3241, 0x00); + SC5336_2l_write_register(ViPipe, 0x3243, 0x01); + SC5336_2l_write_register(ViPipe, 0x3248, 0x02); + SC5336_2l_write_register(ViPipe, 0x3249, 0x0b); + SC5336_2l_write_register(ViPipe, 0x3253, 0x10); + SC5336_2l_write_register(ViPipe, 0x3258, 0x0c); + SC5336_2l_write_register(ViPipe, 0x3301, 0x0a); + SC5336_2l_write_register(ViPipe, 0x3305, 0x00); + SC5336_2l_write_register(ViPipe, 0x3306, 0x58); + SC5336_2l_write_register(ViPipe, 0x3308, 0x08); + SC5336_2l_write_register(ViPipe, 0x3309, 0xb0); + SC5336_2l_write_register(ViPipe, 0x330a, 0x00); + SC5336_2l_write_register(ViPipe, 0x330b, 0xc8); + SC5336_2l_write_register(ViPipe, 0x3314, 0x14); + SC5336_2l_write_register(ViPipe, 0x331f, 0xa1); + SC5336_2l_write_register(ViPipe, 0x3321, 0x10); + SC5336_2l_write_register(ViPipe, 0x3327, 0x14); + SC5336_2l_write_register(ViPipe, 0x3328, 0x0b); + SC5336_2l_write_register(ViPipe, 0x3329, 0x0e); + SC5336_2l_write_register(ViPipe, 0x3333, 0x10); + SC5336_2l_write_register(ViPipe, 0x3334, 0x40); + SC5336_2l_write_register(ViPipe, 0x3356, 0x10); + SC5336_2l_write_register(ViPipe, 0x3364, 0x5e); + SC5336_2l_write_register(ViPipe, 0x338f, 0x80); + SC5336_2l_write_register(ViPipe, 0x3390, 0x09); + SC5336_2l_write_register(ViPipe, 0x3391, 0x0b); + SC5336_2l_write_register(ViPipe, 0x3392, 0x0f); + SC5336_2l_write_register(ViPipe, 0x3393, 0x10); + SC5336_2l_write_register(ViPipe, 0x3394, 0x16); + SC5336_2l_write_register(ViPipe, 0x3395, 0x98); + SC5336_2l_write_register(ViPipe, 0x3396, 0x08); + SC5336_2l_write_register(ViPipe, 0x3397, 0x09); + SC5336_2l_write_register(ViPipe, 0x3398, 0x0f); + SC5336_2l_write_register(ViPipe, 0x3399, 0x0a); + SC5336_2l_write_register(ViPipe, 0x339a, 0x18); + SC5336_2l_write_register(ViPipe, 0x339b, 0x60); + SC5336_2l_write_register(ViPipe, 0x339c, 0xff); + SC5336_2l_write_register(ViPipe, 0x33ad, 0x0c); + SC5336_2l_write_register(ViPipe, 0x33ae, 0x5c); + SC5336_2l_write_register(ViPipe, 0x33af, 0x52); + SC5336_2l_write_register(ViPipe, 0x33b1, 0xa0); + SC5336_2l_write_register(ViPipe, 0x33b2, 0x38); + SC5336_2l_write_register(ViPipe, 0x33b3, 0x18); + SC5336_2l_write_register(ViPipe, 0x33f8, 0x00); + SC5336_2l_write_register(ViPipe, 0x33f9, 0x60); + SC5336_2l_write_register(ViPipe, 0x33fa, 0x00); + SC5336_2l_write_register(ViPipe, 0x33fb, 0x80); + SC5336_2l_write_register(ViPipe, 0x33fc, 0x0b); + SC5336_2l_write_register(ViPipe, 0x33fd, 0x1f); + SC5336_2l_write_register(ViPipe, 0x349f, 0x03); + SC5336_2l_write_register(ViPipe, 0x34a6, 0x0b); + SC5336_2l_write_register(ViPipe, 0x34a7, 0x1f); + SC5336_2l_write_register(ViPipe, 0x34a8, 0x08); + SC5336_2l_write_register(ViPipe, 0x34a9, 0x08); + SC5336_2l_write_register(ViPipe, 0x34aa, 0x00); + SC5336_2l_write_register(ViPipe, 0x34ab, 0xd0); + SC5336_2l_write_register(ViPipe, 0x34ac, 0x00); + SC5336_2l_write_register(ViPipe, 0x34ad, 0xf0); + SC5336_2l_write_register(ViPipe, 0x34f8, 0x3f); + SC5336_2l_write_register(ViPipe, 0x34f9, 0x08); + SC5336_2l_write_register(ViPipe, 0x3630, 0xc0); + SC5336_2l_write_register(ViPipe, 0x3631, 0x83); + SC5336_2l_write_register(ViPipe, 0x3632, 0x54); + SC5336_2l_write_register(ViPipe, 0x3633, 0x33); + SC5336_2l_write_register(ViPipe, 0x3638, 0xcf); + SC5336_2l_write_register(ViPipe, 0x363f, 0xc0); + SC5336_2l_write_register(ViPipe, 0x3641, 0x38); + SC5336_2l_write_register(ViPipe, 0x3670, 0x56); + SC5336_2l_write_register(ViPipe, 0x3674, 0xc0); + SC5336_2l_write_register(ViPipe, 0x3675, 0xa0); + SC5336_2l_write_register(ViPipe, 0x3676, 0xa0); + SC5336_2l_write_register(ViPipe, 0x3677, 0x83); + SC5336_2l_write_register(ViPipe, 0x3678, 0x86); + SC5336_2l_write_register(ViPipe, 0x3679, 0x8a); + SC5336_2l_write_register(ViPipe, 0x367c, 0x08); + SC5336_2l_write_register(ViPipe, 0x367d, 0x0f); + SC5336_2l_write_register(ViPipe, 0x367e, 0x08); + SC5336_2l_write_register(ViPipe, 0x367f, 0x0f); + SC5336_2l_write_register(ViPipe, 0x3696, 0x23); + SC5336_2l_write_register(ViPipe, 0x3697, 0x33); + SC5336_2l_write_register(ViPipe, 0x3698, 0x34); + SC5336_2l_write_register(ViPipe, 0x36a0, 0x09); + SC5336_2l_write_register(ViPipe, 0x36a1, 0x0f); + SC5336_2l_write_register(ViPipe, 0x36b0, 0x85); + SC5336_2l_write_register(ViPipe, 0x36b1, 0x8a); + SC5336_2l_write_register(ViPipe, 0x36b2, 0x95); + SC5336_2l_write_register(ViPipe, 0x36b3, 0xa6); + SC5336_2l_write_register(ViPipe, 0x36b4, 0x09); + SC5336_2l_write_register(ViPipe, 0x36b5, 0x0b); + SC5336_2l_write_register(ViPipe, 0x36b6, 0x0f); + SC5336_2l_write_register(ViPipe, 0x36ea, 0x0c); + SC5336_2l_write_register(ViPipe, 0x370f, 0x01); + SC5336_2l_write_register(ViPipe, 0x3721, 0x6c); + SC5336_2l_write_register(ViPipe, 0x3722, 0x89); + SC5336_2l_write_register(ViPipe, 0x3724, 0x21); + SC5336_2l_write_register(ViPipe, 0x3725, 0xb4); + SC5336_2l_write_register(ViPipe, 0x3727, 0x14); + SC5336_2l_write_register(ViPipe, 0x3771, 0x89); + SC5336_2l_write_register(ViPipe, 0x3772, 0x89); + SC5336_2l_write_register(ViPipe, 0x3773, 0xc5); + SC5336_2l_write_register(ViPipe, 0x377a, 0x0b); + SC5336_2l_write_register(ViPipe, 0x377b, 0x1f); + SC5336_2l_write_register(ViPipe, 0x37fa, 0x0c); + SC5336_2l_write_register(ViPipe, 0x3900, 0x0d); + SC5336_2l_write_register(ViPipe, 0x3901, 0x00); + SC5336_2l_write_register(ViPipe, 0x3904, 0x04); + SC5336_2l_write_register(ViPipe, 0x3905, 0x8c); + SC5336_2l_write_register(ViPipe, 0x391d, 0x04); + SC5336_2l_write_register(ViPipe, 0x391f, 0x49); + SC5336_2l_write_register(ViPipe, 0x3926, 0x21); + SC5336_2l_write_register(ViPipe, 0x3933, 0x80); + SC5336_2l_write_register(ViPipe, 0x3934, 0x0a); + SC5336_2l_write_register(ViPipe, 0x3935, 0x00); + SC5336_2l_write_register(ViPipe, 0x3936, 0xff); + SC5336_2l_write_register(ViPipe, 0x3937, 0x75); + SC5336_2l_write_register(ViPipe, 0x3938, 0x74); + SC5336_2l_write_register(ViPipe, 0x393c, 0x1e); + SC5336_2l_write_register(ViPipe, 0x39dc, 0x02); + SC5336_2l_write_register(ViPipe, 0x3e00, 0x00); + SC5336_2l_write_register(ViPipe, 0x3e01, 0x70); + SC5336_2l_write_register(ViPipe, 0x3e02, 0x00); + SC5336_2l_write_register(ViPipe, 0x3e09, 0x00); + SC5336_2l_write_register(ViPipe, 0x440d, 0x10); + SC5336_2l_write_register(ViPipe, 0x440e, 0x02); + SC5336_2l_write_register(ViPipe, 0x450d, 0x18); + SC5336_2l_write_register(ViPipe, 0x4819, 0x0b); + SC5336_2l_write_register(ViPipe, 0x481b, 0x06); + SC5336_2l_write_register(ViPipe, 0x481d, 0x17); + SC5336_2l_write_register(ViPipe, 0x481f, 0x05); + SC5336_2l_write_register(ViPipe, 0x4821, 0x0b); + SC5336_2l_write_register(ViPipe, 0x4823, 0x06); + SC5336_2l_write_register(ViPipe, 0x4825, 0x05); + SC5336_2l_write_register(ViPipe, 0x4827, 0x05); + SC5336_2l_write_register(ViPipe, 0x4829, 0x09); + SC5336_2l_write_register(ViPipe, 0x5780, 0x66); + SC5336_2l_write_register(ViPipe, 0x5787, 0x08); + SC5336_2l_write_register(ViPipe, 0x5788, 0x03); + SC5336_2l_write_register(ViPipe, 0x5789, 0x00); + SC5336_2l_write_register(ViPipe, 0x578a, 0x08); + SC5336_2l_write_register(ViPipe, 0x578b, 0x03); + SC5336_2l_write_register(ViPipe, 0x578c, 0x00); + SC5336_2l_write_register(ViPipe, 0x578d, 0x40); + SC5336_2l_write_register(ViPipe, 0x5790, 0x08); + SC5336_2l_write_register(ViPipe, 0x5791, 0x04); + SC5336_2l_write_register(ViPipe, 0x5792, 0x01); + SC5336_2l_write_register(ViPipe, 0x5793, 0x08); + SC5336_2l_write_register(ViPipe, 0x5794, 0x04); + SC5336_2l_write_register(ViPipe, 0x5795, 0x01); + SC5336_2l_write_register(ViPipe, 0x5799, 0x46); + SC5336_2l_write_register(ViPipe, 0x57aa, 0x2a); + SC5336_2l_write_register(ViPipe, 0x5ae0, 0xfe); + SC5336_2l_write_register(ViPipe, 0x5ae1, 0x40); + SC5336_2l_write_register(ViPipe, 0x5ae2, 0x38); + SC5336_2l_write_register(ViPipe, 0x5ae3, 0x30); + SC5336_2l_write_register(ViPipe, 0x5ae4, 0x0c); + SC5336_2l_write_register(ViPipe, 0x5ae5, 0x38); + SC5336_2l_write_register(ViPipe, 0x5ae6, 0x30); + SC5336_2l_write_register(ViPipe, 0x5ae7, 0x28); + SC5336_2l_write_register(ViPipe, 0x5ae8, 0x3f); + SC5336_2l_write_register(ViPipe, 0x5ae9, 0x34); + SC5336_2l_write_register(ViPipe, 0x5aea, 0x2c); + SC5336_2l_write_register(ViPipe, 0x5aeb, 0x3f); + SC5336_2l_write_register(ViPipe, 0x5aec, 0x34); + SC5336_2l_write_register(ViPipe, 0x5aed, 0x2c); + SC5336_2l_write_register(ViPipe, 0x36e9, 0x44); + SC5336_2l_write_register(ViPipe, 0x37f9, 0x44); + if (0x00 == SC5336_2l_read_register(ViPipe, 0x3040)) { + SC5336_2l_write_register(ViPipe, 0x3258, 0x0c); + SC5336_2l_write_register(ViPipe, 0x3249, 0x0b); + SC5336_2l_write_register(ViPipe, 0x3934, 0x0a); + SC5336_2l_write_register(ViPipe, 0x3935, 0x00); + SC5336_2l_write_register(ViPipe, 0x3937, 0x75); + } else if (0x03 == SC5336_2l_read_register(ViPipe, 0x3040)) { + SC5336_2l_write_register(ViPipe, 0x3258, 0x08); + SC5336_2l_write_register(ViPipe, 0x3249, 0x07); + SC5336_2l_write_register(ViPipe, 0x3934, 0x05); + SC5336_2l_write_register(ViPipe, 0x3935, 0x07); + SC5336_2l_write_register(ViPipe, 0x3937, 0x74); + } + SC5336_2l_write_register(ViPipe, 0x0100, 0x01); + SC5336_2l_default_reg_init(ViPipe); + + SC5336_2l_write_register(ViPipe, 0x0100, 0x01); + + if (0x00 == SC5336_2l_read_register(ViPipe, 0x3040)) { + printf("ViPipe:%d,===SC5336_2L 1618P 30fps 10bit LINE Init OK!===\n", ViPipe); + } else if (0x03 == SC5336_2l_read_register(ViPipe, 0x3040)) { + printf("ViPipe:%d,===SC5336_2L 1620P 30fps 10bit LINE Init OK!===\n", ViPipe); + } +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f23/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f23/Makefile new file mode 100644 index 00000000..9a364ba1 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f23/f23_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f23/f23_cmos.c new file mode 100644 index 00000000..5d6a6859 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f23/f23_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f23/f23_cmos_ex.h new file mode 100644 index 00000000..cd4e52a3 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f23/f23_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f23/f23_cmos_param.h new file mode 100644 index 00000000..4672b9d3 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f23/f23_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f23/f23_sensor_ctl.c new file mode 100644 index 00000000..8ae66aa0 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f35/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f35/Makefile new file mode 100644 index 00000000..43d630ab --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f35/f35_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f35/f35_cmos.c new file mode 100644 index 00000000..fb3c80ab --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f35/f35_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f35/f35_cmos_ex.h new file mode 100644 index 00000000..d57c9347 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f35/f35_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f35/f35_cmos_param.h new file mode 100644 index 00000000..d555b50c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f35/f35_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f35/f35_sensor_ctl.c new file mode 100644 index 00000000..4d8eb216 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f37p/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f37p/Makefile new file mode 100644 index 00000000..20147a16 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f37p/f37p_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f37p/f37p_cmos.c new file mode 100644 index 00000000..a8b49b1e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f37p/f37p_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f37p/f37p_cmos_ex.h new file mode 100644 index 00000000..de0465e0 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f37p/f37p_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f37p/f37p_cmos_param.h new file mode 100644 index 00000000..3648a52b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f37p/f37p_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_f37p/f37p_sensor_ctl.c new file mode 100644 index 00000000..fce19875 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_k06/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_k06/Makefile new file mode 100644 index 00000000..f1045598 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_k06/k06_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_k06/k06_cmos.c new file mode 100644 index 00000000..1c0d0086 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_k06/k06_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_k06/k06_cmos_ex.h new file mode 100644 index 00000000..e2369605 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_k06/k06_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_k06/k06_cmos_param.h new file mode 100644 index 00000000..9a1ae21d --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_k06/k06_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_k06/k06_sensor_ctl.c new file mode 100644 index 00000000..e9b8cd3d --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_k06/k06_sensor_ctl.c @@ -0,0 +1,361 @@ +#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 val1 = k06_read_register(ViPipe, 0x12); + CVI_U8 val2 = k06_read_register(ViPipe, 0xAA); + CVI_U8 val3 = k06_read_register(ViPipe, 0x27); + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + val1 = 0x30; + val2 = 0x84; + break; + case ISP_SNS_MIRROR: + val1 = 0x10; + val2 = 0x8B; + val3 += 1; + break; + case ISP_SNS_FLIP: + val1 = 0x20; + val2 = 0x84; + break; + case ISP_SNS_MIRROR_FLIP: + val1 = 0x00; + val2 = 0x8B; + val3 += 1; + break; + default: + return; + } + + k06_write_register(ViPipe, 0x12, val1); + k06_write_register(ViPipe, 0xAA, val2); + k06_write_register(ViPipe, 0x27, val3); +} + +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, 0x7F, 0x5E); + 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, 0x46); + k06_write_register(ViPipe, 0x28, 0x15); + k06_write_register(ViPipe, 0x29, 0x04); + k06_write_register(ViPipe, 0x2A, 0x40); + 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, 0x84); + 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, 0x00); + 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, 0x1C); + k06_write_register(ViPipe, 0x89, 0x01); + k06_write_register(ViPipe, 0x6B, 0x20); + k06_write_register(ViPipe, 0x86, 0x40); + k06_write_register(ViPipe, 0x6F, 0x00); + 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, 0xB9); + k06_write_register(ViPipe, 0x56, 0x92); + k06_write_register(ViPipe, 0x59, 0x60); + k06_write_register(ViPipe, 0x5A, 0x01); + k06_write_register(ViPipe, 0x61, 0x00); + k06_write_register(ViPipe, 0x64, 0xC0); + 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, 0x61); + 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, 0x00); + 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, 0x30); + k06_write_register(ViPipe, 0x48, 0x86); + k06_write_register(ViPipe, 0x48, 0x06); + k06_write_register(ViPipe, 0x00, 0x10); + + printf("ViPipe:%d,===K06 1440P 25fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03/Makefile new file mode 100644 index 00000000..16b0c3f0 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03/q03_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03/q03_cmos.c new file mode 100644 index 00000000..59270083 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03/q03_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03/q03_cmos_ex.h new file mode 100644 index 00000000..05a431c1 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03/q03_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03/q03_cmos_param.h new file mode 100644 index 00000000..f6492452 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03/q03_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03/q03_sensor_ctl.c new file mode 100644 index 00000000..5f340ff8 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03p/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03p/Makefile new file mode 100644 index 00000000..c2c419ec --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03p/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_q03p.a +TARGET_SO = $(MW_LIB)/libsns_q03p.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03p/q03p_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03p/q03p_cmos.c new file mode 100644 index 00000000..606f9615 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03p/q03p_cmos.c @@ -0,0 +1,871 @@ +#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 "q03p_cmos_ex.h" +#include "q03p_cmos_param.h" +// #include + +#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 Q03P_ID 03 +#define Q03P_I2C_ADDR_1 0x40 +#define Q03P_I2C_ADDR_2 0x44 +#define Q03P_I2C_ADDR_IS_VALID(addr) ((addr) == Q03P_I2C_ADDR_1 || (addr) == Q03P_I2C_ADDR_2) +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastQ03P[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define Q03P_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastQ03P[dev]) +#define Q03P_SENSOR_SET_CTX(dev, pstCtx) (g_pastQ03P[dev] = pstCtx) +#define Q03P_SENSOR_RESET_CTX(dev) (g_pastQ03P[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunQ03P_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +CVI_U16 g_au16Q03P_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Q03P_L2SMode[VI_MAX_PIPE_NUM] = {0}; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeQ03P_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); +/*****Q03P Lines Range*****/ +#define Q03P_FULL_LINES_MAX (0xFFFF) + +/*****Q03P Register Address*****/ +#define Q03P_SHS1_ADDR 0x01 +#define Q03P_GAIN_ADDR 0x00 +#define Q03P_VMAX_ADDR 0x22 +#define Q03P_FLIP_MIRROR_ADDR 0x12 +#define Q03P_TABLE_END 0xff + +#define Q03P_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 Q03P_MODE_S *pstMode; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + Q03P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astQ03P_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 = Q03P_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_LINEAR; +#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] : g_astQ03P_mode[Q03P_MODE_1296p30].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); + Q03P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_astQ03P_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_astQ03P_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_astQ03P_mode[pstSnsState->u8ImgMode].f32MinFps; + + switch (pstSnsState->u8ImgMode) { + case Q03P_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 > Q03P_FULL_LINES_MAX) ? Q03P_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; + + Q03P_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_U32 gain_table[96] = { + 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,16384,17408,18432,19456,20480,21504,22528,23552,24576,25600,26624,27648, + 28672,29696,30720,31744,32768,34816,36864,38912,40960,43008,45056,47104,49152, + 51200,53248,55296,57344,59392,61440,63488 +}; +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[95]) { + *pu32AgainLin = gain_table[95]; + *pu32AgainDb = 95; + return CVI_SUCCESS; + } + + for (i = 1; i < 95; 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; + + Q03P_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 Q03P_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + Q03P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstMode = &g_astQ03P_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; + + Q03P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = Q03P_MODE_1296p30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_astQ03P_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); + Q03P_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_aunQ03P_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 = q03p_i2c_addr; + pstI2c_data[i].u32AddrByteNum = q03p_addr_byte; + pstI2c_data[i].u32DataByteNum = q03p_data_byte; + } + + //DOL 2t1 Mode Regs + switch (pstSnsState->enWDRMode) { + case WDR_MODE_NONE: + pstI2c_data[LINEAR_SHS1_0_DATA].u32RegAddr = Q03P_SHS1_ADDR; + + pstI2c_data[LINEAR_SHS1_1_DATA].u32RegAddr = Q03P_SHS1_ADDR + 1; + + pstI2c_data[LINEAR_AGAIN_DATA].u32RegAddr = Q03P_GAIN_ADDR; + + pstI2c_data[LINEAR_VMAX_0_DATA].u32RegAddr = Q03P_VMAX_ADDR; + pstI2c_data[LINEAR_VMAX_0_DATA].u8DelayFrmNum = 2; + + pstI2c_data[LINEAR_VMAX_1_DATA].u32RegAddr = Q03P_VMAX_ADDR + 1; + pstI2c_data[LINEAR_VMAX_1_DATA].u8DelayFrmNum = 2; + + pstI2c_data[LINEAR_FLIP_MIRROR].u32RegAddr = Q03P_FLIP_MIRROR_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); + } + + 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); + Q03P_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 (Q03P_RES_IS_1296P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = Q03P_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) +{ + CVI_U8 value = q03p_read_register(ViPipe, Q03P_FLIP_MIRROR_ADDR) & ~0x30; + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + Q03P_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_aeQ03P_MirrorFip[ViPipe] != eSnsMirrorFlip) { + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + value |= 0x00; + break; + case ISP_SNS_MIRROR: + value |= 0x20; + break; + case ISP_SNS_FLIP: + value |= 0x10; + break; + case ISP_SNS_MIRROR_FLIP: + value |= 0x30; + 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_aeQ03P_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + const Q03P_MODE_S *pstMode = CVI_NULL; + + Q03P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = Q03P_MODE_1296p30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstMode = &g_astQ03P_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; + + Q03P_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &q03p_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_astQ03P_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astQ03P_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 = &q03p_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 = q03p_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = q03p_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 (Q03P_I2C_ADDR_IS_VALID(s32I2cAddr)) + q03p_i2c_addr = s32I2cAddr; +} + +static CVI_S32 q03p_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunQ03P_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + Q03P_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)); + + Q03P_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + Q03P_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + Q03P_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 = Q03P_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, Q03P_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, Q03P_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, Q03P_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_au16Q03P_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Q03P_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +ISP_SNS_OBJ_S stSnsQ03P_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = q03p_standby, + .pfnRestart = q03p_restart, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnWriteReg = q03p_write_register, + .pfnReadReg = q03p_read_register, + .pfnSetBusInfo = q03p_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 = q03p_probe, +}; + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03p/q03p_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03p/q03p_cmos_ex.h new file mode 100644 index 00000000..465186df --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03p/q03p_cmos_ex.h @@ -0,0 +1,83 @@ +#ifndef __Q03P_CMOS_EX_H_ +#define __Q03P_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 q03p_linear_regs_e { + LINEAR_SHS1_0_DATA, + LINEAR_SHS1_1_DATA, + LINEAR_AGAIN_DATA, + LINEAR_VMAX_0_DATA, + LINEAR_VMAX_1_DATA, + LINEAR_FLIP_MIRROR, + LINEAR_REGS_NUM +}; + + +typedef enum _Q03P_MODE_E { + Q03P_MODE_1296p30 = 0, + Q03P_MODE_LINEAR_NUM, + Q03P_MODE_1296p30_WDR = Q03P_MODE_LINEAR_NUM, + Q03P_MODE_NUM +} Q03P_MODE_E; + +typedef struct _Q03P_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]; +} Q03P_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastQ03P[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunQ03P_BusInfo[]; +extern CVI_U16 g_au16Q03P_GainMode[]; +extern CVI_U16 g_au16Q03P_L2SMode[]; +extern CVI_U8 q03p_i2c_addr; +extern const CVI_U32 q03p_addr_byte; +extern const CVI_U32 q03p_data_byte; +extern void q03p_init(VI_PIPE ViPipe); +extern void q03p_exit(VI_PIPE ViPipe); +extern void q03p_standby(VI_PIPE ViPipe); +extern void q03p_restart(VI_PIPE ViPipe); +extern int q03p_write_register(VI_PIPE ViPipe, int addr, int data); +extern int q03p_read_register(VI_PIPE ViPipe, int addr); +extern int q03p_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __Q03P_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03p/q03p_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03p/q03p_cmos_param.h new file mode 100644 index 00000000..91d4d43f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03p/q03p_cmos_param.h @@ -0,0 +1,123 @@ +#ifndef __Q03P_CMOS_PARAM_H_ +#define __Q03P_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 "q03p_cmos_ex.h" + +static const Q03P_MODE_S g_astQ03P_mode[Q03P_MODE_NUM] = { + [Q03P_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 = 0.64, /* 1400 * 30 / 0xFFFF */ + .u32HtsDef = 3600, + .u32VtsDef = 1400, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1400, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u16Min = 1024, + .u16Max = 15872,/* 1024 * 15.5 */ + .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, 64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}, + {64, 64, 64, 64, 64, 64, 64, 64, 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, + 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, + {1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, + 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040}, +#endif + }, + }, +}; + +struct combo_dev_attr_s q03p_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {2, 3, 4, -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 /* __Q03P_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03p/q03p_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03p/q03p_sensor_ctl.c new file mode 100644 index 00000000..1c9ee7ec --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/soi_q03p/q03p_sensor_ctl.c @@ -0,0 +1,338 @@ +#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 "q03p_cmos_ex.h" + +#define Q03P_CHIP_ID_HI_ADDR 0x0A +#define Q03P_CHIP_ID_LO_ADDR 0x0B +#define Q03P_CHIP_ID 0x0843 + +//static void q03p_linear_1296p30_init(VI_PIPE ViPipe); +static void q03p_linear_1296p30_init(VI_PIPE ViPipe); +CVI_U8 q03p_i2c_addr = 0x40; /* I2C Address of Q03P */ +const CVI_U32 q03p_addr_byte = 1; +const CVI_U32 q03p_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int q03p_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunQ03P_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, q03p_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; + } + printf("q03p_i2c_init success\n"); + return CVI_SUCCESS; +} + +int q03p_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 q03p_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; + // printf("buff[%d]:%x\n",idx,buf[idx]); + ret = write(g_fd[ViPipe], buf, q03p_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, q03p_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (q03p_data_byte == 1) { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int q03p_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 (q03p_addr_byte == 1) { + buf[idx] = addr & 0xff; + idx++; + } + if (q03p_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, q03p_addr_byte + q03p_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); + // printf("q03p_write_register success\n"); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void q03p_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) + q03p_write_register(ViPipe, addr, data); + } +} + +void q03p_standby(VI_PIPE ViPipe) +{ + q03p_write_register(ViPipe, 0x12, 0x40); +} + +void q03p_restart(VI_PIPE ViPipe) +{ + q03p_write_register(ViPipe, 0x12, 0x40); + delay_ms(20); + q03p_write_register(ViPipe, 0x12, 0x00); +} + +void q03p_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastQ03P[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + q03p_write_register(ViPipe, + g_pastQ03P[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastQ03P[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +int q03p_probe(VI_PIPE ViPipe) +{ + int nVal; + CVI_U16 chip_id; + + usleep(4*1000); + if (q03p_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + printf("q03p_read_register,Q03P_CHIP_ID_HI_ADDR:%x\n ",Q03P_CHIP_ID_HI_ADDR); + nVal = q03p_read_register(ViPipe, Q03P_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; + printf("q03p_read_register,Q03P_CHIP_ID_LO_ADDR:%x\n ",Q03P_CHIP_ID_LO_ADDR); + nVal = q03p_read_register(ViPipe, Q03P_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 != Q03P_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void q03p_init(VI_PIPE ViPipe) +{ + q03p_i2c_init(ViPipe); + + q03p_linear_1296p30_init(ViPipe); + g_pastQ03P[ViPipe]->bInit = CVI_TRUE; +} + +void q03p_exit(VI_PIPE ViPipe) +{ + q03p_i2c_exit(ViPipe); +} + +static void q03p_linear_1296p30_init(VI_PIPE ViPipe) +{ + q03p_write_register(ViPipe, 0x12,0x40); + q03p_write_register(ViPipe, 0x48,0x96); + q03p_write_register(ViPipe, 0x48,0x16); + q03p_write_register(ViPipe, 0x0E,0x11); + q03p_write_register(ViPipe, 0x0F,0x04); + q03p_write_register(ViPipe, 0x10,0x3F); + q03p_write_register(ViPipe, 0x11,0x80); + q03p_write_register(ViPipe, 0x46,0x00); + q03p_write_register(ViPipe, 0x0D,0xA0); + q03p_write_register(ViPipe, 0x57,0x67); + q03p_write_register(ViPipe, 0x58,0x1F); + q03p_write_register(ViPipe, 0x5F,0x41); + q03p_write_register(ViPipe, 0x60,0x28); + q03p_write_register(ViPipe, 0x64,0xD2); + q03p_write_register(ViPipe, 0xA5,0x4F); + q03p_write_register(ViPipe, 0x20,0x84); + q03p_write_register(ViPipe, 0x21,0x03); + q03p_write_register(ViPipe, 0x22,0x78); + q03p_write_register(ViPipe, 0x23,0x05); + q03p_write_register(ViPipe, 0x24,0x40); + q03p_write_register(ViPipe, 0x25,0x10); + q03p_write_register(ViPipe, 0x26,0x52); + q03p_write_register(ViPipe, 0x27,0x74); + q03p_write_register(ViPipe, 0x28,0x15); + q03p_write_register(ViPipe, 0x29,0x03); + q03p_write_register(ViPipe, 0x2A,0x6E); + q03p_write_register(ViPipe, 0x2B,0x13); + q03p_write_register(ViPipe, 0x2C,0x00); + q03p_write_register(ViPipe, 0x2D,0x00); + q03p_write_register(ViPipe, 0x2E,0x4A); + q03p_write_register(ViPipe, 0x2F,0x64); + q03p_write_register(ViPipe, 0x41,0x84); + q03p_write_register(ViPipe, 0x42,0x24); + q03p_write_register(ViPipe, 0x47,0x42); + q03p_write_register(ViPipe, 0x76,0x40); + q03p_write_register(ViPipe, 0x77,0x0B); + q03p_write_register(ViPipe, 0x80,0x03); + q03p_write_register(ViPipe, 0xAF,0x22); + q03p_write_register(ViPipe, 0xAB,0x00); + q03p_write_register(ViPipe, 0x1D,0x00); + q03p_write_register(ViPipe, 0x1E,0x04); + q03p_write_register(ViPipe, 0x6C,0x40); + q03p_write_register(ViPipe, 0x6E,0x2C); + q03p_write_register(ViPipe, 0x70,0xD9); + q03p_write_register(ViPipe, 0x71,0xD5); + q03p_write_register(ViPipe, 0x72,0xD2); + q03p_write_register(ViPipe, 0x73,0x59); + q03p_write_register(ViPipe, 0x74,0x02); + q03p_write_register(ViPipe, 0x78,0x98); + q03p_write_register(ViPipe, 0x89,0x01); + q03p_write_register(ViPipe, 0x6B,0x20); + q03p_write_register(ViPipe, 0x86,0x40); + q03p_write_register(ViPipe, 0x0C,0x10); + q03p_write_register(ViPipe, 0x31,0x10); + q03p_write_register(ViPipe, 0x32,0x31); + q03p_write_register(ViPipe, 0x33,0x5C); + q03p_write_register(ViPipe, 0x34,0x24); + q03p_write_register(ViPipe, 0x35,0x20); + q03p_write_register(ViPipe, 0x3A,0xA0); + q03p_write_register(ViPipe, 0x3B,0x00); + q03p_write_register(ViPipe, 0x3C,0xDC); + q03p_write_register(ViPipe, 0x3D,0xF0); + q03p_write_register(ViPipe, 0x3E,0xBC); + q03p_write_register(ViPipe, 0x56,0x10); + q03p_write_register(ViPipe, 0x59,0x54); + q03p_write_register(ViPipe, 0x5A,0x00); + q03p_write_register(ViPipe, 0x61,0x00); + q03p_write_register(ViPipe, 0x85,0x4A); + q03p_write_register(ViPipe, 0x8A,0x00); + q03p_write_register(ViPipe, 0x8D,0x67); + q03p_write_register(ViPipe, 0x91,0x08); + q03p_write_register(ViPipe, 0x94,0xA0); + q03p_write_register(ViPipe, 0x9C,0x61); + q03p_write_register(ViPipe, 0xA7,0x00); + q03p_write_register(ViPipe, 0xA9,0x4C); + q03p_write_register(ViPipe, 0x5B,0xA0); + q03p_write_register(ViPipe, 0x5C,0x84); + q03p_write_register(ViPipe, 0x5D,0x86); + q03p_write_register(ViPipe, 0x5E,0x03); + q03p_write_register(ViPipe, 0x65,0x02); + q03p_write_register(ViPipe, 0x66,0xC4); + q03p_write_register(ViPipe, 0x67,0x48); + q03p_write_register(ViPipe, 0x68,0x00); + q03p_write_register(ViPipe, 0x69,0x74); + q03p_write_register(ViPipe, 0x6A,0x22); + q03p_write_register(ViPipe, 0x7A,0x77); + q03p_write_register(ViPipe, 0x8F,0x90); + q03p_write_register(ViPipe, 0x45,0x01); + q03p_write_register(ViPipe, 0xA4,0xC7); + q03p_write_register(ViPipe, 0x97,0x20); + q03p_write_register(ViPipe, 0x13,0x81); + q03p_write_register(ViPipe, 0x96,0x84); + q03p_write_register(ViPipe, 0x4A,0x01); + q03p_write_register(ViPipe, 0xB1,0x00); + q03p_write_register(ViPipe, 0xA1,0x0F); + q03p_write_register(ViPipe, 0xB5,0x0C); + q03p_write_register(ViPipe, 0x7E,0x48); + q03p_write_register(ViPipe, 0x9E,0xF0); + q03p_write_register(ViPipe, 0x50,0x02); + q03p_write_register(ViPipe, 0x49,0x10); + q03p_write_register(ViPipe, 0x7F,0x56); + q03p_write_register(ViPipe, 0x8C,0xFF); + q03p_write_register(ViPipe, 0x8E,0x00); + q03p_write_register(ViPipe, 0x8B,0x01); + q03p_write_register(ViPipe, 0xBC,0x11); + q03p_write_register(ViPipe, 0x82,0x00); + q03p_write_register(ViPipe, 0x19,0x20); + q03p_write_register(ViPipe, 0x1B,0x4B); + q03p_write_register(ViPipe, 0x12,0x00); + q03p_write_register(ViPipe, 0x48,0x96); + q03p_write_register(ViPipe, 0x48,0x16); + q03p_default_reg_init(ViPipe); + printf("ViPipe:%d,===Q03P 1296P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307/Makefile new file mode 100644 index 00000000..e89c0e11 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307/imx307_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307/imx307_cmos.c new file mode 100644 index 00000000..15cabfa3 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307/imx307_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307/imx307_cmos_ex.h new file mode 100644 index 00000000..f1405f88 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307/imx307_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307/imx307_cmos_param.h new file mode 100644 index 00000000..967cebe9 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307/imx307_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307/imx307_sensor_ctl.c new file mode 100644 index 00000000..c76af052 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_2L/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_2L/Makefile new file mode 100644 index 00000000..304509b3 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_2L/imx307_2l_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_2L/imx307_2l_cmos.c new file mode 100644 index 00000000..5d1b8375 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_2L/imx307_2l_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_2L/imx307_2l_cmos_ex.h new file mode 100644 index 00000000..abdddde7 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_2L/imx307_2l_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_2L/imx307_2l_cmos_param.h new file mode 100644 index 00000000..ad2475a1 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_2L/imx307_2l_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_2L/imx307_2l_sensor_ctl.c new file mode 100644 index 00000000..3a6a472e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_slave/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_slave/Makefile new file mode 100644 index 00000000..39bacf8e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_slave/imx307_slave_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_slave/imx307_slave_cmos.c new file mode 100644 index 00000000..848dea55 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_slave/imx307_slave_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_slave/imx307_slave_cmos_ex.h new file mode 100644 index 00000000..bfcc7b47 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_slave/imx307_slave_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_slave/imx307_slave_cmos_param.h new file mode 100644 index 00000000..558cdd93 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_slave/imx307_slave_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx307_slave/imx307_slave_sensor_ctl.c new file mode 100644 index 00000000..d925384c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327/Makefile new file mode 100644 index 00000000..c0d94bc4 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327/imx327_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327/imx327_cmos.c new file mode 100644 index 00000000..d6c03368 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327/imx327_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327/imx327_cmos_ex.h new file mode 100644 index 00000000..22f02af1 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327/imx327_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327/imx327_cmos_param.h new file mode 100644 index 00000000..30ca7f88 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327/imx327_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327/imx327_sensor_ctl.c new file mode 100644 index 00000000..542170ca --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_2L/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_2L/Makefile new file mode 100644 index 00000000..7570d61b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_2L/imx327_2l_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_2L/imx327_2l_cmos.c new file mode 100644 index 00000000..a5a75e56 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_2L/imx327_2l_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_2L/imx327_2l_cmos_ex.h new file mode 100644 index 00000000..7998d059 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_2L/imx327_2l_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_2L/imx327_2l_cmos_param.h new file mode 100644 index 00000000..bef9b2e8 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_2L/imx327_2l_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_2L/imx327_2l_sensor_ctl.c new file mode 100644 index 00000000..7f310848 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_fpga/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_fpga/Makefile new file mode 100644 index 00000000..77b5fb33 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_fpga/imx327_fpga_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_fpga/imx327_fpga_cmos.c new file mode 100644 index 00000000..a953be26 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 * 10); + + 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 * 10 / 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 = 0x2; + 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 <= 10) { + 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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_fpga/imx327_fpga_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_fpga/imx327_fpga_cmos_ex.h new file mode 100644 index 00000000..83bcf6cf --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_fpga/imx327_fpga_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_fpga/imx327_fpga_cmos_param.h new file mode 100644 index 00000000..1417aadf --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 = 10, + .f32MinFps = 0.09, /* 750 *30 / 0x3FFFF */ + .u32HtsDef = 0x4D58, + .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 = 5, + .f32MinFps = 0.09, /* 750 *30 / 0x3FFFF */ + .u32HtsDef = 0x4D58, + .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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_fpga/imx327_fpga_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_fpga/imx327_fpga_sensor_ctl.c new file mode 100644 index 00000000..587da40a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_fpga/imx327_fpga_sensor_ctl.c @@ -0,0 +1,371 @@ +#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 + + imx327_fpga_default_reg_init(ViPipe); + imx327_fpga_write_register(ViPipe, 0x3000, 0x00); // STANDBY + delay_ms(20); // delay + 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_slave/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_slave/Makefile new file mode 100644 index 00000000..95045e73 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_slave/imx327_slave_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_slave/imx327_slave_cmos.c new file mode 100644 index 00000000..09249cfd --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_slave/imx327_slave_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_slave/imx327_slave_cmos_ex.h new file mode 100644 index 00000000..c561542b --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_slave/imx327_slave_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_slave/imx327_slave_cmos_param.h new file mode 100644 index 00000000..5977e675 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_slave/imx327_slave_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_slave/imx327_slave_sensor_ctl.c new file mode 100644 index 00000000..54d461ab --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_sublvds/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_sublvds/Makefile new file mode 100644 index 00000000..db74d8c9 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_sublvds/imx327_sublvds_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_sublvds/imx327_sublvds_cmos.c new file mode 100644 index 00000000..7ca3f7d5 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_sublvds/imx327_sublvds_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_sublvds/imx327_sublvds_cmos_ex.h new file mode 100644 index 00000000..493a18f0 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_sublvds/imx327_sublvds_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_sublvds/imx327_sublvds_cmos_param.h new file mode 100644 index 00000000..8d39343f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_sublvds/imx327_sublvds_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx327_sublvds/imx327_sublvds_sensor_ctl.c new file mode 100644 index 00000000..48704c34 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx335/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx335/Makefile new file mode 100644 index 00000000..f2aa5187 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx335/imx335_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx335/imx335_cmos.c new file mode 100644 index 00000000..42fe05b5 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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 >= 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 = 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx335/imx335_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx335/imx335_cmos_ex.h new file mode 100644 index 00000000..d0fdd46f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx335/imx335_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx335/imx335_cmos_param.h new file mode 100644 index 00000000..791a6698 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx335/imx335_sensor_ctl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/sony_imx335/imx335_sensor_ctl.c new file mode 100644 index 00000000..4c69dd20 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2825/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2825/Makefile new file mode 100644 index 00000000..1c908ce3 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2825/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_tp2825.a +TARGET_SO = $(MW_LIB)/libsns_tp2825.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2825/tp2825_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2825/tp2825_cmos.c new file mode 100644 index 00000000..605760f8 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2825/tp2825_cmos.c @@ -0,0 +1,277 @@ +#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 "tp2825_cmos_ex.h" +#include "tp2825_cmos_param.h" + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_COMMBUS_U g_auntp2825_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +ISP_SNS_STATE_S *g_pasttp2825[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define TP2825_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pasttp2825[dev]) +#define TP2825_SENSOR_SET_CTX(dev, pstCtx) (g_pasttp2825[dev] = pstCtx) +#define TP2825_SENSOR_RESET_CTX(dev) (g_pasttp2825[dev] = CVI_NULL) + +#define TP2825_RES_IS_1440P(w, h) ((w) <= 2560 && (h) <= 1440) +#define TP2825_ID 0x2825 +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const tp2825_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + TP2825_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_asttp2825_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); + TP2825_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); + TP2825_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + + if (pstSensorImageMode->f32Fps <= 30) { + if (TP2825_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) { + u8SensorImageMode = TP2825_MODE_1440P_30P; + } 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; + + TP2825_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->u8ImgMode = TP2825_MODE_1440P_30P; + 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; + + TP2825_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &tp2825_rx_attr, sizeof(*pstRxAttr)); + //CVI_TRACE_SNS(CVI_DBG_INFO, "get tp2825_rx0_attr\n"); + + pstRxAttr->img_size.width = g_asttp2825_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_asttp2825_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 = &tp2825_rx_attr; + + + 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; + + 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 = tp2825_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = tp2825_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 tp2825_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_auntp2825_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + TP2825_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)); + + TP2825_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + TP2825_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + TP2825_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 = TP2825_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, TP2825_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 stSnsTP2825_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnMirrorFlip = CVI_NULL, + .pfnStandby = CVI_NULL, + .pfnRestart = CVI_NULL, + .pfnWriteReg = tp2825_write_register, + .pfnReadReg = tp2825_read_register, + .pfnSetBusInfo = tp2825_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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2825/tp2825_cmos_ctrl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2825/tp2825_cmos_ctrl.c new file mode 100644 index 00000000..9a23499c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2825/tp2825_cmos_ctrl.c @@ -0,0 +1,425 @@ +#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 +#include "cvi_sns_ctrl.h" +#include "tp2825_cmos_ex.h" + +const CVI_U8 tp2825_i2c_addr = 0x45; /* I2C slave address of tp2825, SA0=0:0x44, SA0=1:0x45*/ +const CVI_U32 tp2825_addr_byte = 1; +const CVI_U32 tp2825_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; +static pthread_t g_tp2825_thid; + + +#define SYSFS_GPIO_DIR "/sys/class/gpio" +#define MAX_BUF 64 + +#define tp2825_BLUE_SCREEN 0 + + +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 TP2825_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 TP2825_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) + TP2825_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 TP2825_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) + TP2825_GPIO_Export(gpio); + + TP2825_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 tp2825_sys_init(VI_PIPE ViPipe) +{ + (void) ViPipe; + +#ifdef 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 (TP2825_GPIO_SetValue(CVI_GPIOB_12, 1) != 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "set reset gpio error!\n"); + return CVI_FAILURE; + } +#ifdef 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 tp2825_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + int ret; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + + u8DevNum = g_auntp2825_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, tp2825_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 tp2825_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 tp2825_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 (tp2825_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, tp2825_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, tp2825_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (tp2825_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + printf("i2c r 0x%x = 0x%x\n", addr, data); + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int tp2825_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 (tp2825_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + if (tp2825_data_byte == 2) + buf[idx++] = (data >> 8) & 0xff; + + // add data byte 0 + buf[idx++] = data & 0xff; + + ret = write(g_fd[ViPipe], buf, tp2825_addr_byte + tp2825_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 tp2825_init_setting(VI_PIPE ViPipe, CVI_U8 mode) +{ + //unsigned char tmp; + tp2825_write_register(ViPipe, 0x02, 0x50);//Mpage + tp2825_write_register(ViPipe, 0x05, 0x00); + tp2825_write_register(ViPipe, 0x06, 0x32); + tp2825_write_register(ViPipe, 0x07, 0xC0); + tp2825_write_register(ViPipe, 0x08, 0x00); + tp2825_write_register(ViPipe, 0x09, 0x24); + tp2825_write_register(ViPipe, 0x0A, 0x48); + tp2825_write_register(ViPipe, 0x0B, 0xC0); + tp2825_write_register(ViPipe, 0x0C, 0x03); + tp2825_write_register(ViPipe, 0x0D, 0x50); + tp2825_write_register(ViPipe, 0x0E, 0x00); + tp2825_write_register(ViPipe, 0x0F, 0x00); + tp2825_write_register(ViPipe, 0x10, 0x00); + tp2825_write_register(ViPipe, 0x11, 0x40); + tp2825_write_register(ViPipe, 0x12, 0x60); + tp2825_write_register(ViPipe, 0x13, 0x00); + tp2825_write_register(ViPipe, 0x14, 0x00); + tp2825_write_register(ViPipe, 0x15, 0x23); + tp2825_write_register(ViPipe, 0x16, 0x1B); + tp2825_write_register(ViPipe, 0x17, 0x00); + tp2825_write_register(ViPipe, 0x18, 0x38); + tp2825_write_register(ViPipe, 0x19, 0xA0); + tp2825_write_register(ViPipe, 0x1A, 0x5A); + tp2825_write_register(ViPipe, 0x1B, 0x00); + //PAGE0 + if (mode == TP2825_MODE_1440P_30P) { + tp2825_write_register(ViPipe, 0x1C, 0x0C); + tp2825_write_register(ViPipe, 0x1D, 0xE2); + } else if (mode == TP2825_MODE_1440P_25P) { + tp2825_write_register(ViPipe, 0x1C, 0x0F); + tp2825_write_register(ViPipe, 0x1D, 0x76); + } + tp2825_write_register(ViPipe, 0x1E, 0x80); + tp2825_write_register(ViPipe, 0x1F, 0x80); + tp2825_write_register(ViPipe, 0x20, 0x50); + tp2825_write_register(ViPipe, 0x21, 0x84); + tp2825_write_register(ViPipe, 0x22, 0x36); + tp2825_write_register(ViPipe, 0x23, 0x3C); + tp2825_write_register(ViPipe, 0x24, 0x04); + tp2825_write_register(ViPipe, 0x25, 0xFF); + tp2825_write_register(ViPipe, 0x26, 0x05); + tp2825_write_register(ViPipe, 0x27, 0xAD); + tp2825_write_register(ViPipe, 0x28, 0x00); + tp2825_write_register(ViPipe, 0x29, 0x48); + tp2825_write_register(ViPipe, 0x2A, 0x30); + tp2825_write_register(ViPipe, 0x2B, 0x60); + tp2825_write_register(ViPipe, 0x2C, 0x2A); + tp2825_write_register(ViPipe, 0x2D, 0x58); + tp2825_write_register(ViPipe, 0x2E, 0x70); + tp2825_write_register(ViPipe, 0x2F, 0x00); + tp2825_write_register(ViPipe, 0x30, 0x74); + tp2825_write_register(ViPipe, 0x31, 0x58); + tp2825_write_register(ViPipe, 0x32, 0x9F); + tp2825_write_register(ViPipe, 0x33, 0x60); + tp2825_write_register(ViPipe, 0x34, 0x00); + tp2825_write_register(ViPipe, 0x35, 0x15); + tp2825_write_register(ViPipe, 0x36, 0xDC); + tp2825_write_register(ViPipe, 0x37, 0x00); + tp2825_write_register(ViPipe, 0x38, 0x40); + tp2825_write_register(ViPipe, 0x39, 0x48); + tp2825_write_register(ViPipe, 0x3A, 0x12); + tp2825_write_register(ViPipe, 0x3B, 0x26); + tp2825_write_register(ViPipe, 0x3C, 0x00); + tp2825_write_register(ViPipe, 0x3D, 0x60); + tp2825_write_register(ViPipe, 0x3E, 0x00); + tp2825_write_register(ViPipe, 0x3F, 0x00); + tp2825_write_register(ViPipe, 0x40, 0x00); + tp2825_write_register(ViPipe, 0x41, 0x00); + tp2825_write_register(ViPipe, 0x42, 0x00); + tp2825_write_register(ViPipe, 0x43, 0x00); + tp2825_write_register(ViPipe, 0x44, 0x00); + tp2825_write_register(ViPipe, 0x45, 0x00); + tp2825_write_register(ViPipe, 0x46, 0x00); + tp2825_write_register(ViPipe, 0x47, 0x00); + tp2825_write_register(ViPipe, 0x48, 0x00); + tp2825_write_register(ViPipe, 0x49, 0x00); + tp2825_write_register(ViPipe, 0x4A, 0x00); + tp2825_write_register(ViPipe, 0x4B, 0x00); + tp2825_write_register(ViPipe, 0x4C, 0x43); + tp2825_write_register(ViPipe, 0x4D, 0x00); + tp2825_write_register(ViPipe, 0x4E, 0x0D); + tp2825_write_register(ViPipe, 0x4F, 0x00); + tp2825_write_register(ViPipe, 0xF0, 0x00); + tp2825_write_register(ViPipe, 0xF1, 0x00); + tp2825_write_register(ViPipe, 0xF2, 0x00); + tp2825_write_register(ViPipe, 0xF3, 0x00); + tp2825_write_register(ViPipe, 0xF4, 0x20); + tp2825_write_register(ViPipe, 0xF5, 0x10); + tp2825_write_register(ViPipe, 0xF6, 0x00); + tp2825_write_register(ViPipe, 0xF7, 0x00); + tp2825_write_register(ViPipe, 0xF8, 0x00); + tp2825_write_register(ViPipe, 0xF9, 0x00); + tp2825_write_register(ViPipe, 0xFA, 0x03); + tp2825_write_register(ViPipe, 0xFB, 0x00); + tp2825_write_register(ViPipe, 0xFC, 0x00); + + printf("ViPipe:%d,===tp28251440P 30fps 10bit LINE Init OK!===\n", ViPipe); +} + +void tp2825_init(VI_PIPE ViPipe) +{ + if (tp2825_sys_init(ViPipe) != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "TP2825 sys init fail\n"); + return; + } + + delay_ms(20); + + if (tp2825_i2c_init(ViPipe) != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "TP2825 i2c init fail\n"); + return; + } + + syslog(LOG_DEBUG, "Loading Techpoint tp2825 sensor\n"); + + // check sensor chip id + tp2825_write_register(ViPipe, 0x40, 0x0); + if (tp2825_read_register(ViPipe, 0xfe) != 0x28 || + tp2825_read_register(ViPipe, 0xff) != 0x25) { + syslog(LOG_DEBUG, "read tp2825 chip id fail\n"); + return; + } + + if (g_pasttp2825[ViPipe]->u8ImgMode == TP2825_MODE_1440P_30P) + syslog(LOG_DEBUG, "Techpoint tp2825 1440 30FPS\n"); + else + syslog(LOG_DEBUG, "Techpoint tp2825 1440 25FPS\n"); + + tp2825_init_setting(ViPipe, g_pasttp2825[ViPipe]->u8ImgMode); +#if tp2825_BLUE_SCREEN + tp2825_write_register(ViPipe, 0x40, 0x00); + tp2825_write_register(ViPipe, 0x2A, 0x34); +#endif +} + +void tp2825_exit(VI_PIPE ViPipe) +{ + if (g_tp2825_thid) + pthread_kill(g_tp2825_thid, SIGQUIT); + + tp2825_i2c_exit(ViPipe); +} diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2825/tp2825_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2825/tp2825_cmos_ex.h new file mode 100644 index 00000000..33dd03f7 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2825/tp2825_cmos_ex.h @@ -0,0 +1,62 @@ +#ifndef __tp2825_CMOS_EX_H_ +#define __tp2825_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 _tp2825_MODE_E { + TP2825_MODE_1440P_25P, + TP2825_MODE_1440P_30P, + TP2825_MODE_NUM +} tp2825_MODE_E; + +typedef struct _tp2825_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]; +} tp2825_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pasttp2825[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_auntp2825_BusInfo[]; +extern const CVI_U8 tp2825_i2c_addr; +extern const CVI_U32 tp2825_addr_byte; +extern const CVI_U32 tp2825_data_byte; +extern void tp2825_init(VI_PIPE ViPipe); +extern void tp2825_exit(VI_PIPE ViPipe); +extern void tp2825_standby(VI_PIPE ViPipe); +extern void tp2825_restart(VI_PIPE ViPipe); +extern int tp2825_write_register(VI_PIPE ViPipe, int addr, int data); +extern int tp2825_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __tp2825_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2825/tp2825_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2825/tp2825_cmos_param.h new file mode 100644 index 00000000..29f1a109 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2825/tp2825_cmos_param.h @@ -0,0 +1,89 @@ +#ifndef __tp2825_CMOS_PARAM_H_ +#define __tp2825_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 "tp2825_cmos_ex.h" + +static const tp2825_MODE_S g_asttp2825_mode[TP2825_MODE_NUM] = { + [TP2825_MODE_1440P_30P] = { + .name = "1440p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + }, + [TP2825_MODE_1440P_25P] = { + .name = "1440p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 2560, + .u32Height = 1440, + }, + .stMaxSize = { + .u32Width = 2560, + .u32Height = 1440, + }, + }, + }, +}; + +struct combo_dev_attr_s tp2825_rx_attr = { + .input_mode = INPUT_MODE_BT1120, + .mac_clk = RX_MAC_CLK_400M, + .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, + 12, 11, 14, 13, + 8, 15, 10, 9, + }, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __tp2825_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2863/Makefile b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2863/Makefile new file mode 100644 index 00000000..3ff418d0 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2863/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_tp2863.a +TARGET_SO = $(MW_LIB)/libsns_tp2863.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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2863/tp2863_cmos.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2863/tp2863_cmos.c new file mode 100644 index 00000000..43f70486 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2863/tp2863_cmos.c @@ -0,0 +1,336 @@ +#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 "tp2863_cmos_ex.h" +#include "tp2863_cmos_param.h" + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_COMMBUS_U g_aunTP2863_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = {.s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = {.s8I2cDev = -1}}; + +ISP_SNS_STATE_S *g_pastTP2863[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define TP2863_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastTP2863[dev]) +#define TP2863_SENSOR_SET_CTX(dev, pstCtx) (g_pastTP2863[dev] = pstCtx) +#define TP2863_SENSOR_RESET_CTX(dev) (g_pastTP2863[dev] = CVI_NULL) + +#define TP2863_RES_IS_720P_25(w, h, f) ((w) == 1280 && (h) == 720 && (f) == 25) +#define TP2863_RES_IS_720P_30(w, h, f) ((w) == 1280 && (h) == 720 && (f) == 30) +#define TP2863_RES_IS_1080P_25(w, h, f) ((w) == 1920 && (h) == 1080 && (f) == 25) +#define TP2863_RES_IS_1080P_30(w, h, f) ((w) == 1920 && (h) == 1080 && (f) == 30) +#define TP2863_ID 0x2863 +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const TP2863_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + TP2863_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_astTP2863_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); + TP2863_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); + TP2863_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + + if (pstSensorImageMode->f32Fps <= 30) + { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (TP2863_RES_IS_720P_25(pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps)) { + u8SensorImageMode = TP2863_MODE_720P_25P; + } else if (TP2863_RES_IS_720P_30(pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps)) { + u8SensorImageMode = TP2863_MODE_720P_30P; + } else if (TP2863_RES_IS_1080P_25(pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps)) { + u8SensorImageMode = TP2863_MODE_1080P_25P; + } else if (TP2863_RES_IS_1080P_30(pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps)) { + u8SensorImageMode = TP2863_MODE_1080P_30P; + } 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! 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; + + TP2863_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->u8ImgMode = TP2863_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; + + TP2863_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &tp2863_rx_attr, sizeof(*pstRxAttr)); + // CVI_TRACE_SNS(CVI_DBG_INFO, "get tp2863_rx0_attr\n"); + + pstRxAttr->img_size.width = g_astTP2863_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_astTP2863_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 = &tp2863_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + 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 = tp2863_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = tp2863_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 tp2863_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunTP2863_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + TP2863_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)); + + TP2863_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + TP2863_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + TP2863_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 = TP2863_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, TP2863_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 stSnsTP2863_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnMirrorFlip = CVI_NULL, + .pfnStandby = CVI_NULL, + .pfnRestart = CVI_NULL, + .pfnWriteReg = tp2863_write_register, + .pfnReadReg = tp2863_read_register, + .pfnSetBusInfo = tp2863_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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2863/tp2863_cmos_ex.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2863/tp2863_cmos_ex.h new file mode 100644 index 00000000..b4d6fa84 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2863/tp2863_cmos_ex.h @@ -0,0 +1,63 @@ +#ifndef __TP2863_CMOS_EX_H_ +#define __TP2863_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 _TP2863_MODE_E +{ + TP2863_MODE_1080P_30P, + TP2863_MODE_1080P_25P, + TP2863_MODE_720P_30P, + TP2863_MODE_720P_25P, + TP2863_MODE_NUM +} TP2863_MODE_E; +typedef struct _TP2863_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]; +} TP2863_MODE_S; +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ +extern ISP_SNS_STATE_S *g_pastTP2863[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunTP2863_BusInfo[]; +extern const CVI_U8 tp2863_i2c_addr; +extern const CVI_U32 tp2863_addr_byte; +extern const CVI_U32 tp2863_data_byte; +extern void tp2863_init(VI_PIPE ViPipe); +extern void tp2863_exit(VI_PIPE ViPipe); +extern void tp2863_standby(VI_PIPE ViPipe); +extern void tp2863_restart(VI_PIPE ViPipe); +extern int tp2863_write_register(VI_PIPE ViPipe, int addr, int data); +extern int tp2863_read_register(VI_PIPE ViPipe, int addr); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + +#endif /* __TP2863_CMOS_EX_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2863/tp2863_cmos_param.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2863/tp2863_cmos_param.h new file mode 100644 index 00000000..a43e22da --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2863/tp2863_cmos_param.h @@ -0,0 +1,123 @@ +#ifndef __TP2863_CMOS_PARAM_H_ +#define __TP2863_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 "tp2863_cmos_ex.h" + +static const TP2863_MODE_S g_astTP2863_mode[TP2863_MODE_NUM] = { + [TP2863_MODE_1080P_30P] = { + .name = "1080p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + }, + [TP2863_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, + }, + }, + }, + [TP2863_MODE_720P_30P] = { + .name = "720p30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1280, + .u32Height = 720, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1280, + .u32Height = 720, + }, + .stMaxSize = { + .u32Width = 1280, + .u32Height = 720, + }, + }, + }, + [TP2863_MODE_720P_25P] = { + .name = "720p25", + .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 tp2863_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_400M, + .mipi_attr = { + .raw_data_type = YUV422_8BIT, + .lane_id = {0, 2, 1, -1, -1}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_NONE, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __TP2863_CMOS_PARAM_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2863/tp2863_sensor_ctrl.c b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2863/tp2863_sensor_ctrl.c new file mode 100644 index 00000000..e57d9187 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/isp/sensor/sg200x/techpoint_tp2863/tp2863_sensor_ctrl.c @@ -0,0 +1,593 @@ +#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 "tp2863_cmos_ex.h" + +const CVI_U8 tp2863_i2c_addr = 0x44; /* I2C slave address of TP2863, SA0=0:0x44, SA0=1:0x45*/ +const CVI_U32 tp2863_addr_byte = 1; +const CVI_U32 tp2863_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ...(VI_MAX_PIPE_NUM - 1)] = -1}; + +#define TP2863_BLUE_SCREEN 0 + +enum +{ + CH_1 = 0, + CH_2 = 1, + CH_ALL = 4, + MIPI_PAGE = 8, +}; + +enum +{ + STD_TVI, // TVI + STD_HDA, // AHD +}; + +enum +{ + HD25, + HD30, // 1280x720 + FHD25, + FHD30, // 1920x1080 +}; + +enum +{ + MIPI_1CH2LANE_297M, + MIPI_1CH2LANE_594M, + MIPI_2CH2LANE_594M, + MIPI_2CH2LANE_297M, +}; + +int tp2863_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + int ret; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + + u8DevNum = g_aunTP2863_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, tp2863_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 tp2863_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 tp2863_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 (tp2863_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, tp2863_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, tp2863_data_byte); + if (ret < 0) + { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return 0; + } + + // pack read back data + data = 0; + if (tp2863_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 tp2863_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 (tp2863_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + if (tp2863_data_byte == 2) + buf[idx++] = (data >> 8) & 0xff; + + // add data byte 0 + buf[idx++] = data & 0xff; + + ret = write(g_fd[ViPipe], buf, tp2863_addr_byte + tp2863_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 = tp2863_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; +} + +void TP2863_decoder_init(VI_PIPE ViPipe, unsigned char ch, unsigned char fmt, unsigned char std) +{ + unsigned char tmp; + const unsigned char REG42_43[] = {0x01, 0x02, 0x00, 0x00, 0x03}; + const unsigned char MASK42_43[] = {0xfe, 0xfd, 0xff, 0xff, 0xfc}; + + tp2863_write_register(ViPipe, 0x40, ch); + tp2863_write_register(ViPipe, 0x06, 0x12); // default value + tp2863_write_register(ViPipe, 0x50, 0x00); // VIN1/3 + tp2863_write_register(ViPipe, 0x51, 0x00); + tp2863_write_register(ViPipe, 0x54, 0x03); + + if (HD25 == fmt) + { + tmp = tp2863_read_register(ViPipe, 0x42); + tmp |= REG42_43[ch]; + tp2863_write_register(ViPipe, 0x42, tmp); + + tmp = tp2863_read_register(ViPipe, 0x43); + tmp &= MASK42_43[ch]; + tp2863_write_register(ViPipe, 0x43, tmp); + + tp2863_write_register(ViPipe, 0x02, 0x42); + tp2863_write_register(ViPipe, 0x07, 0xc0); + tp2863_write_register(ViPipe, 0x0b, 0xc0); + tp2863_write_register(ViPipe, 0x0c, 0x13); + tp2863_write_register(ViPipe, 0x0d, 0x50); + + tp2863_write_register(ViPipe, 0x15, 0x13); + tp2863_write_register(ViPipe, 0x16, 0x15); + tp2863_write_register(ViPipe, 0x17, 0x00); + tp2863_write_register(ViPipe, 0x18, 0x19); + tp2863_write_register(ViPipe, 0x19, 0xd0); + tp2863_write_register(ViPipe, 0x1a, 0x25); + tp2863_write_register(ViPipe, 0x1c, 0x07); // 1280*720, 25fps + tp2863_write_register(ViPipe, 0x1d, 0xbc); // 1280*720, 25fps + + tp2863_write_register(ViPipe, 0x20, 0x30); + tp2863_write_register(ViPipe, 0x21, 0x84); + tp2863_write_register(ViPipe, 0x22, 0x36); + tp2863_write_register(ViPipe, 0x23, 0x3c); + + tp2863_write_register(ViPipe, 0x2b, 0x60); + tp2863_write_register(ViPipe, 0x2c, 0x0a); + tp2863_write_register(ViPipe, 0x2d, 0x30); + tp2863_write_register(ViPipe, 0x2e, 0x70); + + tp2863_write_register(ViPipe, 0x30, 0x48); + tp2863_write_register(ViPipe, 0x31, 0xbb); + tp2863_write_register(ViPipe, 0x32, 0x2e); + tp2863_write_register(ViPipe, 0x33, 0x90); + + tp2863_write_register(ViPipe, 0x35, 0x25); + tp2863_write_register(ViPipe, 0x39, 0x08); + + if (STD_HDA == std) + { + tp2863_write_register(ViPipe, 0x02, 0x46); + + tp2863_write_register(ViPipe, 0x0d, 0x71); + + tp2863_write_register(ViPipe, 0x20, 0x40); + tp2863_write_register(ViPipe, 0x21, 0x46); + + tp2863_write_register(ViPipe, 0x25, 0xfe); + tp2863_write_register(ViPipe, 0x26, 0x01); + + tp2863_write_register(ViPipe, 0x2c, 0x3a); + tp2863_write_register(ViPipe, 0x2d, 0x5a); + tp2863_write_register(ViPipe, 0x2e, 0x40); + + tp2863_write_register(ViPipe, 0x30, 0x9e); + tp2863_write_register(ViPipe, 0x31, 0x20); + tp2863_write_register(ViPipe, 0x32, 0x10); + tp2863_write_register(ViPipe, 0x33, 0x90); + } + } + else if (HD30 == fmt) + { + tmp = tp2863_read_register(ViPipe, 0x42); + tmp |= REG42_43[ch]; + tp2863_write_register(ViPipe, 0x42, tmp); + + tmp = tp2863_read_register(ViPipe, 0x43); + tmp &= MASK42_43[ch]; + tp2863_write_register(ViPipe, 0x43, tmp); + + tp2863_write_register(ViPipe, 0x02, 0x42); + tp2863_write_register(ViPipe, 0x07, 0xc0); + tp2863_write_register(ViPipe, 0x0b, 0xc0); + tp2863_write_register(ViPipe, 0x0c, 0x13); + tp2863_write_register(ViPipe, 0x0d, 0x50); + + tp2863_write_register(ViPipe, 0x15, 0x13); + tp2863_write_register(ViPipe, 0x16, 0x15); + tp2863_write_register(ViPipe, 0x17, 0x00); + tp2863_write_register(ViPipe, 0x18, 0x19); + tp2863_write_register(ViPipe, 0x19, 0xd0); + tp2863_write_register(ViPipe, 0x1a, 0x25); + tp2863_write_register(ViPipe, 0x1c, 0x06); // 1280*720, 30fps + tp2863_write_register(ViPipe, 0x1d, 0x72); // 1280*720, 30fps + + tp2863_write_register(ViPipe, 0x20, 0x30); + tp2863_write_register(ViPipe, 0x21, 0x84); + tp2863_write_register(ViPipe, 0x22, 0x36); + tp2863_write_register(ViPipe, 0x23, 0x3c); + + tp2863_write_register(ViPipe, 0x2b, 0x60); + tp2863_write_register(ViPipe, 0x2c, 0x0a); + tp2863_write_register(ViPipe, 0x2d, 0x30); + tp2863_write_register(ViPipe, 0x2e, 0x70); + + tp2863_write_register(ViPipe, 0x30, 0x48); + tp2863_write_register(ViPipe, 0x31, 0xbb); + tp2863_write_register(ViPipe, 0x32, 0x2e); + tp2863_write_register(ViPipe, 0x33, 0x90); + + tp2863_write_register(ViPipe, 0x35, 0x25); + tp2863_write_register(ViPipe, 0x39, 0x08); + + if (STD_HDA == std) + { + tp2863_write_register(ViPipe, 0x02, 0x46); + + tp2863_write_register(ViPipe, 0x0d, 0x70); + + tp2863_write_register(ViPipe, 0x20, 0x40); + tp2863_write_register(ViPipe, 0x21, 0x46); + + tp2863_write_register(ViPipe, 0x25, 0xfe); + tp2863_write_register(ViPipe, 0x26, 0x01); + + tp2863_write_register(ViPipe, 0x2c, 0x3a); + tp2863_write_register(ViPipe, 0x2d, 0x5a); + tp2863_write_register(ViPipe, 0x2e, 0x40); + + tp2863_write_register(ViPipe, 0x30, 0x9d); + tp2863_write_register(ViPipe, 0x31, 0xca); + tp2863_write_register(ViPipe, 0x32, 0x01); + tp2863_write_register(ViPipe, 0x33, 0xd0); + } + } + else if (FHD25 == fmt) + { + tmp = tp2863_read_register(ViPipe, 0x42); + tmp &= MASK42_43[ch]; + tp2863_write_register(ViPipe, 0x42, tmp); + + tmp = tp2863_read_register(ViPipe, 0x43); + tmp &= MASK42_43[ch]; + tp2863_write_register(ViPipe, 0x43, tmp); + + tp2863_write_register(ViPipe, 0x02, 0x40); + tp2863_write_register(ViPipe, 0x07, 0xc0); + tp2863_write_register(ViPipe, 0x0b, 0xc0); + tp2863_write_register(ViPipe, 0x0c, 0x03); + tp2863_write_register(ViPipe, 0x0d, 0x50); + + tp2863_write_register(ViPipe, 0x15, 0x03); + tp2863_write_register(ViPipe, 0x16, 0xd2); + tp2863_write_register(ViPipe, 0x17, 0x80); + tp2863_write_register(ViPipe, 0x18, 0x29); + tp2863_write_register(ViPipe, 0x19, 0x38); + tp2863_write_register(ViPipe, 0x1a, 0x47); + + tp2863_write_register(ViPipe, 0x1c, 0x0a); // 1920*1080, 25fps + tp2863_write_register(ViPipe, 0x1d, 0x50); // + + tp2863_write_register(ViPipe, 0x20, 0x30); + tp2863_write_register(ViPipe, 0x21, 0x84); + tp2863_write_register(ViPipe, 0x22, 0x36); + tp2863_write_register(ViPipe, 0x23, 0x3c); + + tp2863_write_register(ViPipe, 0x2b, 0x60); + tp2863_write_register(ViPipe, 0x2c, 0x0a); + tp2863_write_register(ViPipe, 0x2d, 0x30); + tp2863_write_register(ViPipe, 0x2e, 0x70); + + tp2863_write_register(ViPipe, 0x30, 0x48); + tp2863_write_register(ViPipe, 0x31, 0xbb); + tp2863_write_register(ViPipe, 0x32, 0x2e); + tp2863_write_register(ViPipe, 0x33, 0x90); + + tp2863_write_register(ViPipe, 0x35, 0x05); + tp2863_write_register(ViPipe, 0x39, 0x0C); + + if (STD_HDA == std) + { + tp2863_write_register(ViPipe, 0x02, 0x44); + + tp2863_write_register(ViPipe, 0x0d, 0x73); + + tp2863_write_register(ViPipe, 0x15, 0x01); + tp2863_write_register(ViPipe, 0x16, 0xf0); + tp2863_write_register(ViPipe, 0x18, 0x2a); + tp2863_write_register(ViPipe, 0x20, 0x3c); + tp2863_write_register(ViPipe, 0x21, 0x46); + + tp2863_write_register(ViPipe, 0x25, 0xfe); + tp2863_write_register(ViPipe, 0x26, 0x0d); + + tp2863_write_register(ViPipe, 0x2c, 0x3a); + tp2863_write_register(ViPipe, 0x2d, 0x54); + tp2863_write_register(ViPipe, 0x2e, 0x40); + + tp2863_write_register(ViPipe, 0x30, 0xa5); + tp2863_write_register(ViPipe, 0x31, 0x86); + tp2863_write_register(ViPipe, 0x32, 0xfb); + tp2863_write_register(ViPipe, 0x33, 0x60); + } + } + else if (FHD30 == fmt) + { + tmp = tp2863_read_register(ViPipe, 0x42); + tmp &= MASK42_43[ch]; + tp2863_write_register(ViPipe, 0x42, tmp); + + tmp = tp2863_read_register(ViPipe, 0x43); + tmp &= MASK42_43[ch]; + tp2863_write_register(ViPipe, 0x43, tmp); + + tp2863_write_register(ViPipe, 0x02, 0x40); + tp2863_write_register(ViPipe, 0x07, 0xc0); + tp2863_write_register(ViPipe, 0x0b, 0xc0); + tp2863_write_register(ViPipe, 0x0c, 0x03); + tp2863_write_register(ViPipe, 0x0d, 0x50); + + tp2863_write_register(ViPipe, 0x15, 0x03); + tp2863_write_register(ViPipe, 0x16, 0xd2); + tp2863_write_register(ViPipe, 0x17, 0x80); + tp2863_write_register(ViPipe, 0x18, 0x29); + tp2863_write_register(ViPipe, 0x19, 0x38); + tp2863_write_register(ViPipe, 0x1a, 0x47); + tp2863_write_register(ViPipe, 0x1c, 0x08); // 1920*1080, 30fps + tp2863_write_register(ViPipe, 0x1d, 0x98); // + + tp2863_write_register(ViPipe, 0x20, 0x30); + tp2863_write_register(ViPipe, 0x21, 0x84); + tp2863_write_register(ViPipe, 0x22, 0x36); + tp2863_write_register(ViPipe, 0x23, 0x3c); + + tp2863_write_register(ViPipe, 0x2b, 0x60); + tp2863_write_register(ViPipe, 0x2c, 0x0a); + tp2863_write_register(ViPipe, 0x2d, 0x30); + tp2863_write_register(ViPipe, 0x2e, 0x70); + + tp2863_write_register(ViPipe, 0x30, 0x48); + tp2863_write_register(ViPipe, 0x31, 0xbb); + tp2863_write_register(ViPipe, 0x32, 0x2e); + tp2863_write_register(ViPipe, 0x33, 0x90); + + tp2863_write_register(ViPipe, 0x35, 0x05); + tp2863_write_register(ViPipe, 0x39, 0x0C); + + if (STD_HDA == std) + { + tp2863_write_register(ViPipe, 0x02, 0x44); + + tp2863_write_register(ViPipe, 0x0d, 0x72); + + tp2863_write_register(ViPipe, 0x15, 0x01); + tp2863_write_register(ViPipe, 0x16, 0xf0); + tp2863_write_register(ViPipe, 0x18, 0x2a); + + tp2863_write_register(ViPipe, 0x20, 0x38); + tp2863_write_register(ViPipe, 0x21, 0x46); + + tp2863_write_register(ViPipe, 0x25, 0xfe); + tp2863_write_register(ViPipe, 0x26, 0x0d); + + tp2863_write_register(ViPipe, 0x2c, 0x3a); + tp2863_write_register(ViPipe, 0x2d, 0x54); + tp2863_write_register(ViPipe, 0x2e, 0x40); + + tp2863_write_register(ViPipe, 0x30, 0xa5); + tp2863_write_register(ViPipe, 0x31, 0x95); + tp2863_write_register(ViPipe, 0x32, 0xe0); + tp2863_write_register(ViPipe, 0x33, 0x60); + } + } +} + +void TP2863_mipi_out(VI_PIPE ViPipe, unsigned char output) +{ + // mipi setting + tp2863_write_register(ViPipe, 0x40, MIPI_PAGE); // MIPI page + tp2863_write_register(ViPipe, 0x02, 0x78); + tp2863_write_register(ViPipe, 0x03, 0x70); + tp2863_write_register(ViPipe, 0x04, 0x70); + tp2863_write_register(ViPipe, 0x05, 0x70); + tp2863_write_register(ViPipe, 0x06, 0x70); + + tp2863_write_register(ViPipe, 0x13, 0xef); + tp2863_write_register(ViPipe, 0x20, 0x00); + tp2863_write_register(ViPipe, 0x21, 0x22); + tp2863_write_register(ViPipe, 0x22, 0x20); + tp2863_write_register(ViPipe, 0x23, 0x9e); + + if (MIPI_1CH2LANE_297M == output) + { + tp2863_write_register(ViPipe, 0x21, 0x12); + tp2863_write_register(ViPipe, 0x14, 0x41); + tp2863_write_register(ViPipe, 0x15, 0x02); + tp2863_write_register(ViPipe, 0x2a, 0x04); + tp2863_write_register(ViPipe, 0x2b, 0x03); + tp2863_write_register(ViPipe, 0x2c, 0x09); + tp2863_write_register(ViPipe, 0x2e, 0x02); + tp2863_write_register(ViPipe, 0x10, 0xa0); + tp2863_write_register(ViPipe, 0x10, 0x20); + } + else if (MIPI_1CH2LANE_594M == output) + { + tp2863_write_register(ViPipe, 0x21, 0x12); + tp2863_write_register(ViPipe, 0x14, 0x00); // clk + tp2863_write_register(ViPipe, 0x15, 0x01); // clk + tp2863_write_register(ViPipe, 0x2a, 0x08); // LPX + tp2863_write_register(ViPipe, 0x2b, 0x08); // PREP + tp2863_write_register(ViPipe, 0x2c, 0x10); // TRAIL/HS ZERO + tp2863_write_register(ViPipe, 0x2e, 0x0a); + tp2863_write_register(ViPipe, 0x10, 0xa0); + tp2863_write_register(ViPipe, 0x10, 0x20); + } + else if (MIPI_2CH2LANE_297M == output) + { + tp2863_write_register(ViPipe, 0x21, 0x22); + tp2863_write_register(ViPipe, 0x14, 0x41); + tp2863_write_register(ViPipe, 0x15, 0x02); + tp2863_write_register(ViPipe, 0x2a, 0x04); + tp2863_write_register(ViPipe, 0x2b, 0x03); + tp2863_write_register(ViPipe, 0x2c, 0x09); + tp2863_write_register(ViPipe, 0x2e, 0x02); + tp2863_write_register(ViPipe, 0x10, 0xa0); + tp2863_write_register(ViPipe, 0x10, 0x20); + } + else if (MIPI_2CH2LANE_594M == output) + { + tp2863_write_register(ViPipe, 0x21, 0x22); + tp2863_write_register(ViPipe, 0x14, 0x00); + tp2863_write_register(ViPipe, 0x15, 0x01); + tp2863_write_register(ViPipe, 0x2a, 0x08); + tp2863_write_register(ViPipe, 0x2b, 0x08); + tp2863_write_register(ViPipe, 0x2c, 0x10); + tp2863_write_register(ViPipe, 0x2e, 0x0a); + tp2863_write_register(ViPipe, 0x10, 0xa0); + tp2863_write_register(ViPipe, 0x10, 0x20); + } + + /* Enable MIPI CSI2 output */ + tp2863_write_register(ViPipe, 0x28, 0x02); + tp2863_write_register(ViPipe, 0x28, 0x00); +} + +void TP2863_reg_init(VI_PIPE ViPipe, CVI_U8 u8ImgMode) +{ + if (u8ImgMode == TP2863_MODE_1080P_30P) + { + TP2863_decoder_init(ViPipe, CH_1, FHD30, STD_HDA); + TP2863_mipi_out(ViPipe, MIPI_1CH2LANE_297M); + printf("Techpoint TP2863 1080 FHD30\n"); + } + else if (u8ImgMode == TP2863_MODE_1080P_25P) + { + TP2863_decoder_init(ViPipe, CH_1, FHD25, STD_HDA); + TP2863_mipi_out(ViPipe, MIPI_1CH2LANE_297M); + printf("Techpoint TP2863 720 FHD25\n"); + } + else if (u8ImgMode == TP2863_MODE_720P_30P) + { + TP2863_decoder_init(ViPipe, CH_1, HD30, STD_HDA); + TP2863_mipi_out(ViPipe, MIPI_1CH2LANE_297M); + printf("Techpoint TP2863 720 HD30\n"); + } + else if (u8ImgMode == TP2863_MODE_720P_25P) + { + TP2863_decoder_init(ViPipe, CH_1, HD25, STD_HDA); + TP2863_mipi_out(ViPipe, MIPI_1CH2LANE_297M); + printf("Techpoint TP2863 720 HD25\n"); + } +} + +void tp2863_init(VI_PIPE ViPipe) +{ + tp2863_i2c_init(ViPipe); + + syslog(LOG_DEBUG, "Loading Techpoint TP2863 sensor\n"); + + // check sensor chip id + tp2863_write_register(ViPipe, 0x40, 0x0); + if (tp2863_read_register(ViPipe, 0xfe) != 0x28 || + tp2863_read_register(ViPipe, 0xff) != 0x63) + { + syslog(LOG_DEBUG, "read TP2863 chip id fail\n"); + return; + } + + TP2863_reg_init(ViPipe, g_pastTP2863[ViPipe]->u8ImgMode); + + usleep(500 * 1000); + +#if TP2863_BLUE_SCREEN + tp2863_write_register(ViPipe, 0x40, 0x00); + tp2863_write_register(ViPipe, 0x2A, 0x3C); +#endif +} + +void tp2863_exit(VI_PIPE ViPipe) +{ + tp2863_i2c_exit(ViPipe); +} \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/cv180x b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/cv180x new file mode 120000 index 00000000..d177554a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/cv180x @@ -0,0 +1 @@ +cv181x \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/cv181x b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/cv181x new file mode 120000 index 00000000..0629d44f --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/cv181x @@ -0,0 +1 @@ +sg200x \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/bt1120_nvp6021.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/bt1120_nvp6021.h new file mode 100644 index 00000000..b9910bcf --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/bt1120_nvp6021.h @@ -0,0 +1,34 @@ +#ifndef _BT1120_NVP6021_H_ +#define _BT1120_NVP6021_H_ + +#include + +const struct VO_PINMUX nvp6021_pins_cfg = { + .pin_num = 17, + .d_pins = { + {VO_MIPI_TXM2, VO_MUX_BT_DATA0}, + {VO_MIPI_TXP1, VO_MUX_BT_DATA1}, + {VO_MIPI_TXM1, VO_MUX_BT_DATA2}, + {VO_MIPI_TXP0, VO_MUX_BT_DATA3}, + {VO_MIPI_TXM0, VO_MUX_BT_DATA4}, + {VO_MIPI_RXP0, VO_MUX_BT_DATA5}, + {VO_MIPI_TXP3, VO_MUX_BT_DATA6}, + {VO_MIPI_TXM3, VO_MUX_BT_DATA7}, + + {VO_MIPI_TXP4, VO_MUX_BT_DATA8}, + {VO_VIVO_D0, VO_MUX_BT_DATA9}, + {VO_VIVO_D1, VO_MUX_BT_DATA10}, + {VO_VIVO_D2, VO_MUX_BT_DATA11}, + {VO_VIVO_D3, VO_MUX_BT_DATA12}, + {VO_VIVO_D4, VO_MUX_BT_DATA13}, + {VO_VIVO_D9, VO_MUX_BT_DATA14}, + {VO_VIVO_D10, VO_MUX_BT_DATA15}, + {VO_VIVO_CLK, VO_MUX_BT_CLK} + } +}; + +const VO_BT_ATTR_S stNVP6021Cfg = { + .pins = nvp6021_pins_cfg, +}; + +#endif // _BT1120_NVP6021_H_ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/bt656_tp2803.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/bt656_tp2803.h new file mode 100644 index 00000000..681f34d7 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/bt656_tp2803.h @@ -0,0 +1,23 @@ +#ifndef _BT656_TP2803_H_ +#define _BT656_TP2803_H_ + +#include + +const VO_BT_ATTR_S stTP2803Cfg = { + .pins = { + .pin_num = 9, + .d_pins = { + {VO_VIVO_D0, VO_MUX_BT_DATA0}, + {VO_VIVO_D1, VO_MUX_BT_DATA1}, + {VO_VIVO_D2, VO_MUX_BT_DATA2}, + {VO_VIVO_D3, VO_MUX_BT_DATA3}, + {VO_VIVO_D4, VO_MUX_BT_DATA4}, + {VO_VIVO_D5, VO_MUX_BT_DATA5}, + {VO_VIVO_D6, VO_MUX_BT_DATA6}, + {VO_VIVO_D7, VO_MUX_BT_DATA7}, + {VO_VIVO_CLK, VO_MUX_BT_CLK} + } + }, +}; + +#endif // _I80_PARAM_ST7789V_H_ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_3aml069lp01g.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_3aml069lp01g.h new file mode 100644 index 00000000..24fe2e50 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/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) + +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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_gm8775c.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_gm8775c.h new file mode 100644 index 00000000..fece5a09 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/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 +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_GM8775C_1080P_H_ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_hx8394_evb.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_hx8394_evb.h new file mode 100644 index 00000000..c6372e92 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_hx8394_evb.h @@ -0,0 +1,125 @@ +#ifndef _MIPI_TX_PARAM_HX8394_H_ +#define _MIPI_TX_PARAM_HX8394_H_ + +#include +#include + +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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_hx8399_1080p.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_hx8399_1080p.h new file mode 100644 index 00000000..ff900ec4 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/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) + +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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_icn9707.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_icn9707.h new file mode 100644 index 00000000..d2a0bf45 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_icn9707.h @@ -0,0 +1,130 @@ +#ifndef _MIPI_TX_PARAM_ICN9707_H_ +#define _MIPI_TX_PARAM_ICN9707_H_ + +#include +#include + +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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_ili9881c.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_ili9881c.h new file mode 100644 index 00000000..b7cae29d --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_ili9881c.h @@ -0,0 +1,429 @@ +#ifndef _MIPI_TX_PARAM_ILI9881C_H_ +#define _MIPI_TX_PARAM_ILI9881C_H_ + +#include +#include + +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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_ili9881d.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_ili9881d.h new file mode 100644 index 00000000..88d48885 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_ili9881d.h @@ -0,0 +1,418 @@ +#ifndef _MIPI_TX_PARAM_ILI9881D_H_ +#define _MIPI_TX_PARAM_ILI9881D_H_ + +#include +#include + +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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_jd9366ab.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_jd9366ab.h new file mode 100644 index 00000000..3b4bace7 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_jd9366ab.h @@ -0,0 +1,394 @@ +#ifndef _MIPI_TX_PARAM_JD9366AB_H_ +#define _MIPI_TX_PARAM_JD9366AB_H_ + +#include +#include + +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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_jd9852.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_jd9852.h new file mode 100644 index 00000000..6db40ca8 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_jd9852.h @@ -0,0 +1,109 @@ +#ifndef _MIPI_TX_PARAM_JD9852_H_ +#define _MIPI_TX_PARAM_JD9852_H_ + +#include +#include + +#define JD9852_HACT 240 +#define JD9852_HSA 60 +#define JD9852_HBP 50 +#define JD9852_HFP 50 + +#define JD9852_VACT 320 +#define JD9852_VSA 2 +#define JD9852_VBP 2 +#define JD9852_VFP 2 + +#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_JD9852_240x320 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_0, -1, MIPI_TX_LANE_CLK, -1, -1}, + .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 = JD9852_HSA, + .vid_hbp_pixels = JD9852_HBP, + .vid_hfp_pixels = JD9852_HFP, + .vid_hline_pixels = JD9852_HACT, + .vid_vsa_lines = JD9852_VSA, + .vid_vbp_lines = JD9852_VBP, + .vid_vfp_lines = JD9852_VFP, + .vid_active_lines = JD9852_VACT, + .vid_vsa_pos_polarity = true, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = PIXEL_CLK(JD9852), +}; + +const struct hs_settle_s hs_timing_cfg_JD9852_240x320 = {.prepare = 6, .zero = 32, .trail = 1}; + +static CVI_U8 data_JD9852_0[] = {0xdf, 0x98, 0x51, 0xe9}; // PASSWORD +static CVI_U8 data_JD9852_1[] = {0xde, 0x00}; // ---------------- PAGE0 -------------- +static CVI_U8 data_JD9852_2[] = {0xb7, 0x1e, 0x7d, 0x1e, 0x2b}; // VGMP, VGSP, VGMN, VGSN 4.2 +static CVI_U8 data_JD9852_3[] = { + 0xc8, 0x3f, 0x38, 0x33, 0x2f, 0x32, 0x34, 0x2f, 0x2f, 0x2d, + 0x2c, 0x27, 0x1a, 0x14, 0x0a, 0x06, 0x0e, 0x3f, 0x38, 0x33, + 0x2f, 0x32, 0x34, 0x2f, 0x2f, 0x2d, 0x2c, 0x27, 0x1a, 0x14, + 0x0a, 0x06, 0x0e +}; // Set_R_GAMMA +static CVI_U8 data_JD9852_4[] = {0xb9, 0x33, 0x08, 0xcc}; // POW_CTRL +static CVI_U8 data_JD9852_5[] = {0xbb, 0x46, 0x7a, 0x30, 0x40, 0x7c, 0x60, 0x70, 0x70}; // DCDC_SEL +static CVI_U8 data_JD9852_6[] = {0xbc, 0x38, 0x3c}; // VDDD_CTRL +static CVI_U8 data_JD9852_7[] = {0xc0, 0x31, 0x20}; // SETSTBA +static CVI_U8 data_JD9852_8[] = {0xc1, 0x12}; // SETPANEL(default) +static CVI_U8 data_JD9852_9[] = {0xc3, 0x08, 0x00, 0x0a, 0x10, 0x08, 0x54, 0x45, 0x71, 0x2c}; // SETRGBCYC +static CVI_U8 data_JD9852_10[] = { + 0xc4, 0x00, 0xa0, 0x79, 0x0e, 0x0a, 0x16, 0x79, 0x0e, 0x0a, + 0x16, 0x79, 0x0e, 0x0a, 0x16, 0x82, 0x00, 0x03 +}; // SETRGBCYC(default) +static CVI_U8 data_JD9852_11[] = {0xd0, 0x04, 0x0c, 0x6b, 0x0f, 0x07, 0x03}; +static CVI_U8 data_JD9852_12[] = {0xd7, 0x13, 0x00}; +static CVI_U8 data_JD9852_13[] = {0xde, 0x02}; +static CVI_U8 data_JD9852_14[] = {0xb8, 0x1d, 0xa0, 0x2f, 0x04, 0x33}; +static CVI_U8 data_JD9852_15[] = {0xc1, 0x10, 0x66, 0x66, 0x01}; +static CVI_U8 data_JD9852_16[] = {0xde, 0x00}; +static CVI_U8 data_JD9852_17[] = {0x11}; +static CVI_U8 data_JD9852_18[] = {0xde, 0x02}; +static CVI_U8 data_JD9852_19[] = {0xc5, 0x4e, 0x00, 0x00}; +static CVI_U8 data_JD9852_20[] = {0xca, 0x30, 0x20, 0xf4}; +static CVI_U8 data_JD9852_21[] = {0xde, 0x04}; +static CVI_U8 data_JD9852_22[] = {0xd3, 0x3c}; +static CVI_U8 data_JD9852_23[] = {0xde, 0x00}; +static CVI_U8 data_JD9852_24[] = {0x3a, 0x77}; +static CVI_U8 data_JD9852_25[] = {0x29}; + +const struct dsc_instr dsi_init_cmds_JD9852_320x480[] = { + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_JD9852_0}, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_JD9852_1}, + {.delay = 0, .data_type = 0x29, .size = 5, .data = data_JD9852_2}, + {.delay = 0, .data_type = 0x29, .size = 33, .data = data_JD9852_3}, + {.delay = 0, .data_type = 0x29, .size = 4, .data = data_JD9852_4}, + {.delay = 0, .data_type = 0x29, .size = 9, .data = data_JD9852_5}, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_JD9852_6}, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_JD9852_7}, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_JD9852_8}, + {.delay = 0, .data_type = 0x29, .size = 10, .data = data_JD9852_9}, + {.delay = 0, .data_type = 0x29, .size = 18, .data = data_JD9852_10}, + {.delay = 0, .data_type = 0x29, .size = 7, .data = data_JD9852_11}, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_JD9852_12}, + {.delay = 1, .data_type = 0x15, .size = 2, .data = data_JD9852_13}, + {.delay = 0, .data_type = 0x29, .size = 6, .data = data_JD9852_14}, + {.delay = 0, .data_type = 0x29, .size = 5, .data = data_JD9852_15}, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_JD9852_16}, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_JD9852_17}, + {.delay = 1, .data_type = 0x15, .size = 2, .data = data_JD9852_18}, + {.delay = 1, .data_type = 0x29, .size = 4, .data = data_JD9852_19}, + {.delay = 1, .data_type = 0x29, .size = 4, .data = data_JD9852_20}, + {.delay = 1, .data_type = 0x15, .size = 2, .data = data_JD9852_21}, + {.delay = 1, .data_type = 0x15, .size = 2, .data = data_JD9852_22}, + {.delay = 1, .data_type = 0x15, .size = 2, .data = data_JD9852_23}, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_JD9852_24}, + {.delay = 0, .data_type = 0x05, .size = 1, .data = data_JD9852_25} +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_JD9852_H_ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_lt9611.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_lt9611.h new file mode 100644 index 00000000..0c97b1b8 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_lt9611.h @@ -0,0 +1,140 @@ +#ifndef _HDMI_LT9611_H_ +#define _HDMI_LT9611_H_ + +#include "linux/cvi_comm_video.h" + +static struct combo_dev_cfg_s dev_cfg_lt9611_1920x1080_60Hz = { + .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 = 44, + .vid_hbp_pixels = 148, + .vid_hfp_pixels = 88, + .vid_hline_pixels = 1920, + .vid_vsa_lines = 5, + .vid_vbp_lines = 36, + .vid_vfp_lines = 4, + .vid_active_lines = 1080, + .vid_vsa_pos_polarity = true, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 148500, +}; + +static struct combo_dev_cfg_s dev_cfg_lt9611_1920x1080_30Hz = { + .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 = 44, + .vid_hbp_pixels = 148, + .vid_hfp_pixels = 88, + .vid_hline_pixels = 1920, + .vid_vsa_lines = 5, + .vid_vbp_lines = 36, + .vid_vfp_lines = 4, + .vid_active_lines = 1080, + .vid_vsa_pos_polarity = true, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 74250, +}; + +static struct combo_dev_cfg_s dev_cfg_lt9611_1280x720_60Hz = { + .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 = 40, + .vid_hbp_pixels = 220, + .vid_hfp_pixels = 110, + .vid_hline_pixels = 1280, + .vid_vsa_lines = 5, + .vid_vbp_lines = 20, + .vid_vfp_lines = 5, + .vid_active_lines = 720, + .vid_vsa_pos_polarity = true, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 74250, +}; + +static struct combo_dev_cfg_s dev_cfg_lt9611_1024x768_60Hz = { + .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 = 136, + .vid_hbp_pixels = 160, + .vid_hfp_pixels = 24, + .vid_hline_pixels = 1024, + .vid_vsa_lines = 6, + .vid_vbp_lines = 29, + .vid_vfp_lines = 3, + .vid_active_lines = 768, + .vid_vsa_pos_polarity = false, + .vid_hsa_pos_polarity = false, + }, + .pixel_clk = 65000, +}; + +static struct combo_dev_cfg_s dev_cfg_lt9611_1280x1024_60Hz = { + .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 = 112, + .vid_hbp_pixels = 248, + .vid_hfp_pixels = 48, + .vid_hline_pixels = 1280, + .vid_vsa_lines = 3, + .vid_vbp_lines = 38, + .vid_vfp_lines = 1, + .vid_active_lines = 1024, + .vid_vsa_pos_polarity = true, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 108000, +}; + +static struct combo_dev_cfg_s dev_cfg_lt9611_1600x1200_60Hz = { + .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 = 192, + .vid_hbp_pixels = 304, + .vid_hfp_pixels = 64, + .vid_hline_pixels = 1600, + .vid_vsa_lines = 3, + .vid_vbp_lines = 46, + .vid_vfp_lines = 1, + .vid_active_lines = 1200, + .vid_vsa_pos_polarity = true, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = 162000, +}; + +static struct hs_settle_s hs_timing_cfg_lt9611 = { .prepare = 6, .zero = 32, .trail = 5 }; + +#endif // _HDMI_LT9611_H_ \ No newline at end of file diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_nt35521.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_nt35521.h new file mode 100644 index 00000000..9607f21c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_nt35521.h @@ -0,0 +1,200 @@ +#ifndef _MIPI_TX_PARAM_NT35521_H_ +#define _MIPI_TX_PARAM_NT35521_H_ + +#include +#include + +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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_ota7290b.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_ota7290b.h new file mode 100644 index 00000000..cf3e324a --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_ota7290b.h @@ -0,0 +1,547 @@ +#ifndef _MIPI_TX_PARAM_OTA7290B_H_ +#define _MIPI_TX_PARAM_OTA7290B_H_ + +#include +#include + +// Not support BTA +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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_ota7290b_1920.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_ota7290b_1920.h new file mode 100644 index 00000000..0ff10869 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/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 +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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_st7701.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_st7701.h new file mode 100644 index 00000000..9cb59ca8 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/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) + +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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_st7701_hd228001c31.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_st7701_hd228001c31.h new file mode 100644 index 00000000..685b0515 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_st7701_hd228001c31.h @@ -0,0 +1,209 @@ +#ifndef _MIPI_TX_PARAM_ST_7701_HD228001C31_H_ +#define _MIPI_TX_PARAM_ST_7701_HD228001C31_H_ + +#ifndef __UBOOT__ +#include +#include +#else +#include +#endif + +// vendor +#define ST7701_HD228001C31_VACT 552 +#define ST7701_HD228001C31_VSA 2 +#define ST7701_HD228001C31_VBP 20 +#define ST7701_HD228001C31_VFP 20 + +#define ST7701_HD228001C31_HACT 368 +#define ST7701_HD228001C31_HSA 8 +#define ST7701_HD228001C31_HBP 160 +#define ST7701_HD228001C31_HFP 160 + + +// calc +/* +#define ST7701_HD228001C31_VACT 552 +#define ST7701_HD228001C31_VSA 10 +#define ST7701_HD228001C31_VBP 6 +#define ST7701_HD228001C31_VFP 3 + +#define ST7701_HD228001C31_HACT 368 +#define ST7701_HD228001C31_HSA 32 +#define ST7701_HD228001C31_HBP 80 +#define ST7701_HD228001C31_HFP 48 +*/ + +#define HD22_PIXEL_CLK(x) ((x##_VACT + x##_VSA + x##_VBP + x##_VFP) \ + * (x##_HACT + x##_HSA + x##_HBP + x##_HFP) * 75 / 1000) + +struct combo_dev_cfg_s dev_cfg_st7701_368x552 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_CLK, MIPI_TX_LANE_1, -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_HD228001C31_HSA, + .vid_hbp_pixels = ST7701_HD228001C31_HBP, + .vid_hfp_pixels = ST7701_HD228001C31_HFP, + .vid_hline_pixels = ST7701_HD228001C31_HACT, + .vid_vsa_lines = ST7701_HD228001C31_VSA, + .vid_vbp_lines = ST7701_HD228001C31_VBP, + .vid_vfp_lines = ST7701_HD228001C31_VFP, + .vid_active_lines = ST7701_HD228001C31_VACT, + .vid_vsa_pos_polarity = true, + .vid_hsa_pos_polarity = false, + }, + .pixel_clk = HD22_PIXEL_CLK(ST7701_HD228001C31), +}; + +const struct hs_settle_s hs_timing_cfg_st7701_368x552 = { .prepare = 6, .zero = 32, .trail = 1 }; + +#define CVI_U8 uint8_t + +static CVI_U8 data_st7701_hd228001c31_0[] = { 0xff, 0x77, 0x01, 0x00, 0x00, 0x13 }; +static CVI_U8 data_st7701_hd228001c31_1[] = { 0xef, 0x08 }; +static CVI_U8 data_st7701_hd228001c31_2[] = { 0xff, 0x77, 0x01, 0x00, 0x00, 0x10 }; +static CVI_U8 data_st7701_hd228001c31_3[] = { 0xc0, 0x44, 0x00 }; +static CVI_U8 data_st7701_hd228001c31_4[] = { 0xc1, 0x0b, 0x02 }; +static CVI_U8 data_st7701_hd228001c31_5[] = { 0xc2, 0x07, 0x1f }; +static CVI_U8 data_st7701_hd228001c31_6[] = { 0xcc, 0x10 }; + +static CVI_U8 data_st7701_hd228001c31_7[] = { + 0xb0, 0x0F,0x1E,0x25,0x0D,0x11,0x06,0x12,0x08,0x08,0x2A,0x05,0x12,0x10,0x2B,0x32,0x1F +}; +static CVI_U8 data_st7701_hd228001c31_8[] = { + 0xb1, 0x0F,0x1E,0x25,0x0D,0x11,0x05,0x12,0x08,0x08,0x2B,0x05,0x12,0x10,0x2B,0x32,0x1F +}; +static CVI_U8 data_st7701_hd228001c31_9[] = { 0xff, 0x77, 0x01, 0x00, 0x00, 0x11 }; +static CVI_U8 data_st7701_hd228001c31_10[] = { 0xb0, 0x35 }; +static CVI_U8 data_st7701_hd228001c31_11[] = { 0xb1, 0x45 }; +static CVI_U8 data_st7701_hd228001c31_12[] = { 0xb2, 0x87 }; +static CVI_U8 data_st7701_hd228001c31_13[] = { 0xb3, 0x80 }; +static CVI_U8 data_st7701_hd228001c31_14[] = { 0xb5, 0x49 }; +static CVI_U8 data_st7701_hd228001c31_15[] = { 0xb7, 0x85 }; +static CVI_U8 data_st7701_hd228001c31_16[] = { 0xb8, 0x11 }; +//static CVI_U8 data_st7701_hd228001c31_17[] = { 0xb9, 0x10, 0x1f }; +//static CVI_U8 data_st7701_hd228001c31_18[] = { 0xbb, 0x03 }; +static CVI_U8 data_st7701_hd228001c31_19[] = { 0xc0, 0x07 }; +static CVI_U8 data_st7701_hd228001c31_20[] = { 0xc1, 0x78 }; +static CVI_U8 data_st7701_hd228001c31_21[] = { 0xc2, 0x78 }; +static CVI_U8 data_st7701_hd228001c31_22[] = { 0xc8, 0xbe }; +static CVI_U8 data_st7701_hd228001c31_23[] = { 0xd0, 0x88 }; +static CVI_U8 data_st7701_hd228001c31_24[] = { + 0xe0, 0x00, 0x00, 0x02 +}; +static CVI_U8 data_st7701_hd228001c31_25[] = { + 0xe1, 0x03,0x30,0x07,0x30,0x02,0x30,0x06,0x30,0x00,0x44,0x44 +}; +static CVI_U8 data_st7701_hd228001c31_26[] = { + 0xe2, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; +static CVI_U8 data_st7701_hd228001c31_27[] = { 0xe3, 0x00, 0x00, 0x22, 0x00 }; +static CVI_U8 data_st7701_hd228001c31_28[] = { 0xe4, 0x22, 0x00 }; +static CVI_U8 data_st7701_hd228001c31_29[] = { + 0xe5, 0x0A,0x34,0x30,0xE0,0x08,0x32,0x30,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; +static CVI_U8 data_st7701_hd228001c31_30[] = { 0xe6, 0x00, 0x00, 0x22, 0x00 }; +static CVI_U8 data_st7701_hd228001c31_31[] = { 0xe7, 0x22, 0x00 }; +static CVI_U8 data_st7701_hd228001c31_32[] = { + 0xe8, 0x09,0x33,0x30,0xE0,0x07,0x31,0x30,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; +static CVI_U8 data_st7701_hd228001c31_33[] = { + 0xeb, 0x00,0x01,0x10,0x10,0x11,0x00,0x00 +}; +static CVI_U8 data_st7701_hd228001c31_34[] = { + 0xed, 0xFF,0xFF,0xF0,0x45,0xBA,0x2F,0xFF,0xFF,0xFF,0xFF,0xF2,0xAB,0x54,0x0F,0xFF,0xFF +}; +static CVI_U8 data_st7701_hd228001c31_35[] = { + 0xef, 0x08,0x08,0x08,0x45,0x3F,0x54 +}; +static CVI_U8 data_st7701_hd228001c31_36[] = { 0xff, 0x77, 0x01, 0x00, 0x00, 0x13 }; +static CVI_U8 data_st7701_hd228001c31_37[] = { 0xe8, 0x00, 0x0e}; +static CVI_U8 data_st7701_hd228001c31_38[] = { 0x11, 0x00}; +static CVI_U8 data_st7701_hd228001c31_39[] = { 0xE0, 0x00, 0x0C }; +static CVI_U8 data_st7701_hd228001c31_40[] = { 0xE0, 0x00, 0x00 }; +static CVI_U8 data_st7701_hd228001c31_41[] = { 0xFF, 0x77,0x01,0x00,0x00,0x00}; +static CVI_U8 data_st7701_hd228001c31_42[] = { 0x29, 0x00}; + + +//Delay(500); +//bist模式 +//彩条 +/* +static CVI_U8 data_st7701_hd228001c31_43[] = {0xFF,0x77,0x01,0x00,0x00,0x12}; +static CVI_U8 data_st7701_hd228001c31_44[] = {0xd1,0x81,0x10,0x03,0x03,0x08,0x01,0xA0,0x01,0xe0,0xB0,0x01,0xe0,0x03,0x20}; +//static CVI_U8 data_st7701_hd228001c31_45[] = {0xd2,0x00};///grey pattern +//static CVI_U8 data_st7701_hd228001c31_45[] = {0xd2,0x02};///red pattern +static CVI_U8 data_st7701_hd228001c31_45[] = {0xd2,0x08};///colorbar +static CVI_U8 data_st7701_hd228001c31_46[] = {0xFF,0x77,0x01,0x00,0x00,0x10}; +static CVI_U8 data_st7701_hd228001c31_47[] = {0xC2,0x31,0x08}; +*/ + + +// len == 1 , type 0x05 +// len == 2 , type 0x15 or type 23 +// len >= 3 , type 0x29 or type 0x39 +#define TYPE1_DCS_SHORT_WRITE 0x05 +#define TYPE2_DCS_SHORT_WRITE 0x15 +#define TYPE3_DCS_LONG_WRITE 0x39 +#define TYPE3_GENERIC_LONG_WRITE 0x29 +const struct dsc_instr dsi_init_cmds_st7701_368x552[] = { + {.delay = 0, .data_type = 0x39, .size = 6, .data = data_st7701_hd228001c31_0 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_hd228001c31_1 }, + {.delay = 0, .data_type = 0x39, .size = 6, .data = data_st7701_hd228001c31_2 }, + {.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_hd228001c31_3 }, + {.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_hd228001c31_4 }, + {.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_hd228001c31_5 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_hd228001c31_6 }, + {.delay = 0, .data_type = 0x39, .size = 17, .data = data_st7701_hd228001c31_7 }, + {.delay = 0, .data_type = 0x39, .size = 17, .data = data_st7701_hd228001c31_8 }, + {.delay = 0, .data_type = 0x39, .size = 6, .data = data_st7701_hd228001c31_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_hd228001c31_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_hd228001c31_11 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_hd228001c31_12 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_hd228001c31_13 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_hd228001c31_14 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_hd228001c31_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_hd228001c31_16 }, + //{.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_hd228001c31_17 }, + //{.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_hd228001c31_18 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_hd228001c31_19 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_hd228001c31_20 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_st7701_hd228001c31_21 }, + {.delay = 100, .data_type = 0x15, .size = 2, .data = data_st7701_hd228001c31_22 }, + {.delay = 100, .data_type = 0x15, .size = 2, .data = data_st7701_hd228001c31_23 }, + {.delay = 100, .data_type = 0x39, .size = 4, .data = data_st7701_hd228001c31_24 }, + {.delay = 0, .data_type = 0x39, .size = 12, .data = data_st7701_hd228001c31_25 }, + {.delay = 0, .data_type = 0x39, .size = 12, .data = data_st7701_hd228001c31_26 }, + {.delay = 0, .data_type = 0x39, .size = 5, .data = data_st7701_hd228001c31_27 }, + {.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_hd228001c31_28 }, + {.delay = 0, .data_type = 0x39, .size = 17, .data = data_st7701_hd228001c31_29 }, + {.delay = 0, .data_type = 0x39, .size = 5, .data = data_st7701_hd228001c31_30 }, + {.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_hd228001c31_31 }, + {.delay = 0, .data_type = 0x39, .size = 17, .data = data_st7701_hd228001c31_32 }, + {.delay = 0, .data_type = 0x39, .size = 8, .data = data_st7701_hd228001c31_33 }, + {.delay = 0, .data_type = 0x39, .size = 17, .data = data_st7701_hd228001c31_34 }, + {.delay = 0, .data_type = 0x39, .size = 7, .data = data_st7701_hd228001c31_35 }, + {.delay = 0, .data_type = 0x39, .size = 6, .data = data_st7701_hd228001c31_36 }, + {.delay = 254, .data_type = 0x39, .size = 3, .data = data_st7701_hd228001c31_37 }, + {.delay = 254, .data_type = 0x15, .size = 2, .data = data_st7701_hd228001c31_38 }, + {.delay = 254, .data_type = 0x39, .size = 3, .data = data_st7701_hd228001c31_39 }, + {.delay = 0, .data_type = 0x39, .size = 3, .data = data_st7701_hd228001c31_40 }, + {.delay = 254, .data_type = 0x39, .size = 6, .data = data_st7701_hd228001c31_41 }, + {.delay = 254, .data_type = 0x15, .size = 2, .data = data_st7701_hd228001c31_42 }, + /* bist mode vvv */ +/* + {.delay = 0, .data_type = TYPE3_DCS_LONG_WRITE, .size = 6, .data = data_st7701_hd228001c31_43 }, + {.delay = 0, .data_type = TYPE3_DCS_LONG_WRITE, .size = 15, .data = data_st7701_hd228001c31_44 }, + {.delay = 0, .data_type = TYPE2_DCS_SHORT_WRITE, .size = 2, .data = data_st7701_hd228001c31_45 }, + {.delay = 0, .data_type = TYPE3_DCS_LONG_WRITE, .size = 6, .data = data_st7701_hd228001c31_46 }, + {.delay = 0, .data_type = TYPE3_DCS_LONG_WRITE, .size = 3, .data = data_st7701_hd228001c31_47 }, +*/ +/* bist mode ^^^ */ +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_ST_7701_HD22801C31_H_ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_st7785m.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_st7785m.h new file mode 100644 index 00000000..5f8762ae --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_st7785m.h @@ -0,0 +1,96 @@ +#ifndef _MIPI_TX_PARAM_ST7785M_H_ +#define _MIPI_TX_PARAM_ST7785M_H_ + +#include +#include + +#define ST7785M_HACT 240 +#define ST7785M_HSA 10 +#define ST7785M_HBP 80 +#define ST7785M_HFP 80 + +#define ST7785M_VACT 320 +#define ST7785M_VSA 10 +#define ST7785M_VBP 20 +#define ST7785M_VFP 20 + +#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_st7785m_240x320 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_CLK, -1, -1, -1}, + .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 = ST7785M_HSA, + .vid_hbp_pixels = ST7785M_HBP, + .vid_hfp_pixels = ST7785M_HFP, + .vid_hline_pixels = ST7785M_HACT, + .vid_vsa_lines = ST7785M_VSA, + .vid_vbp_lines = ST7785M_VBP, + .vid_vfp_lines = ST7785M_VFP, + .vid_active_lines = ST7785M_VACT, + .vid_vsa_pos_polarity = true, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = PIXEL_CLK(ST7785M), +}; + +const struct hs_settle_s hs_timing_cfg_st7785m_240x320 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_st7785m_0[] = { 0x11 }; +static CVI_U8 data_st7785m_1[] = { 0x36,0x00, 0x00 }; +static CVI_U8 data_st7785m_2[] = { 0x3a,0x00, 0x66}; +static CVI_U8 data_st7785m_3[] = { 0xb0,0x00, 0x10 }; +static CVI_U8 data_st7785m_4[] = { 0xb2,0x00, 0x0c, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x33, 0x00, 0x33 }; +static CVI_U8 data_st7785m_5[] = { 0xb7, 0x00, 0x51 }; +static CVI_U8 data_st7785m_6[] = { 0xbb, 0x00, 0x1e }; +static CVI_U8 data_st7785m_7[] = { 0xc0, 0x00, 0x2c }; +static CVI_U8 data_st7785m_8[] = { 0xc2, 0x00, 0x01 }; +static CVI_U8 data_st7785m_9[] = { 0xc3,0x00, 0x13 }; +static CVI_U8 data_st7785m_10[] = { 0xc6,0x00, 0x0f }; +static CVI_U8 data_st7785m_11[] = { 0xd0,0x00, 0xa7 }; +static CVI_U8 data_st7785m_12[] = { 0xd0,0x00, 0xa4, 0x00, 0xa1 }; +static CVI_U8 data_st7785m_13[] = { 0xe0,0x00, 0xF0, 0x00, 0x0C, 0x00, + 0x14, 0x00, 0x0C, 0x00, 0x0C, 0x00, + 0x09, 0x00, 0x3B, 0x00, 0x44, 0x00, + 0x52, 0x00, 0x3A, 0x00, 0x14, 0x00, + 0x15, 0x00, 0x35, 0x00, 0x3B }; +static CVI_U8 data_st7785m_14[] = { 0xe1,0x00, 0xF0, 0x00, 0x0F, 0x00, + 0x16,0x00, 0x09, 0x00, 0x08, 0x00, + 0x23,0x00, 0x3B, 0x00, 0x33, 0x00, + 0x52,0x00, 0x25, 0x00, 0x0F, 0x00, + 0x11, 0x00, 0x33, 0x00, 0x39 }; + +static CVI_U8 data_st7785m_15[] = { 0x21 }; +static CVI_U8 data_st7785m_16[] = { 0x11 }; +static CVI_U8 data_st7785m_17[] = { 0x29 }; + +const struct dsc_instr dsi_init_cmds_st7785m_240x320[] = { + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_st7785m_0 }, + {.delay = 10, .data_type = 0x29, .size = 3, .data = data_st7785m_1 }, + {.delay = 10, .data_type = 0x29, .size = 3, .data = data_st7785m_2 }, + {.delay = 10, .data_type = 0x29, .size = 3, .data = data_st7785m_3 }, + {.delay = 10, .data_type = 0x29, .size = 11, .data = data_st7785m_4 }, + {.delay = 10, .data_type = 0x29, .size = 3, .data = data_st7785m_5 }, + {.delay = 10, .data_type = 0x29, .size = 3, .data = data_st7785m_6 }, + {.delay = 10, .data_type = 0x29, .size = 3, .data = data_st7785m_7 }, + {.delay = 10, .data_type = 0x29, .size = 3, .data = data_st7785m_8 }, + {.delay = 10, .data_type = 0x29, .size = 3, .data = data_st7785m_9 }, + {.delay = 10, .data_type = 0x29, .size = 3, .data = data_st7785m_10 }, + {.delay = 10, .data_type = 0x29, .size = 3, .data = data_st7785m_11 }, + {.delay = 10, .data_type = 0x29, .size = 5, .data = data_st7785m_12 }, + {.delay = 10, .data_type = 0x29, .size = 29, .data = data_st7785m_13 }, + {.delay = 10, .data_type = 0x29, .size = 29, .data = data_st7785m_14 }, + {.delay = 10, .data_type = 0x05, .size = 1, .data = data_st7785m_15 }, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_st7785m_16 }, + {.delay = 20, .data_type = 0x05, .size = 1, .data = data_st7785m_17 }, + +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_ST7785M_H_ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_st7796s.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_st7796s.h new file mode 100644 index 00000000..0451004c --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_st7796s.h @@ -0,0 +1,95 @@ +#ifndef _MIPI_TX_PARAM_ST7796S_H_ +#define _MIPI_TX_PARAM_ST7796S_H_ + +#include +#include + +#define ST7796S_HACT 320 +#define ST7796S_HSA 20 +#define ST7796S_HBP 40 +#define ST7796S_HFP 10 + +#define ST7796S_VACT 480 +#define ST7796S_VSA 2 +#define ST7796S_VBP 2 +#define ST7796S_VFP 2 + +#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_ST7796S_320x480 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_0, -1, MIPI_TX_LANE_CLK, -1, -1}, + .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 = ST7796S_HSA, + .vid_hbp_pixels = ST7796S_HBP, + .vid_hfp_pixels = ST7796S_HFP, + .vid_hline_pixels = ST7796S_HACT, + .vid_vsa_lines = ST7796S_VSA, + .vid_vbp_lines = ST7796S_VBP, + .vid_vfp_lines = ST7796S_VFP, + .vid_active_lines = ST7796S_VACT, + .vid_vsa_pos_polarity = true, + .vid_hsa_pos_polarity = true, + }, + .pixel_clk = PIXEL_CLK(ST7796S), +}; + +const struct hs_settle_s hs_timing_cfg_ST7796S_320x480 = { .prepare = 6, .zero = 32, .trail = 1 }; + +static CVI_U8 data_ST7796S_0[] = { 0x11 }; // Sleep Out +static CVI_U8 data_ST7796S_1[] = { 0x36, 0x48 }; // Memory Data Access Control +static CVI_U8 data_ST7796S_2[] = { 0x3a, 0x77 }; // Interface Pixel Format +static CVI_U8 data_ST7796S_3[] = { 0xf0, 0xc3 }; // Command Set Control +static CVI_U8 data_ST7796S_4[] = { 0xf0, 0x96 }; +static CVI_U8 data_ST7796S_5[] = { 0xb4, 0x01 }; // , 1-Dot INV +static CVI_U8 data_ST7796S_6[] = { 0xb7, 0xc6 }; +static CVI_U8 data_ST7796S_7[] = { 0xb9, 0x02, 0xe0 }; +static CVI_U8 data_ST7796S_8[] = { 0xc0, 0x80, 0x75 }; // , VGH = 15V, VGL = -10V +static CVI_U8 data_ST7796S_9[] = { 0xc1, 0x13 }; // 4.5V +static CVI_U8 data_ST7796S_10[] = { 0xc2, 0xa7 }; +static CVI_U8 data_ST7796S_11[] = { 0xc5, 0x1d }; // VCOM Control, 1.15V +static CVI_U8 data_ST7796S_12[] = { 0xe8, 0x40, 0x8a, 0x00, 0x00, 0x29, 0x19, 0xa5, 0x33 }; +static CVI_U8 data_ST7796S_13[] = { 0xe0, 0xd0, 0x02, 0x0a, 0x10, + 0x11, 0x0c, 0x35, 0x44, 0x46, + 0x3C, 0x15, 0x13, 0x17, 0x1a }; +static CVI_U8 data_ST7796S_14[] = { 0xe1, 0xd0, 0x01, 0x08, 0x0b, + 0x0c, 0x17, 0x35, 0x44, 0x47, + 0x09, 0x18, 0x17, 0x19, 0x1d }; + +static CVI_U8 data_ST7796S_15[] = { 0x35, 0x00 }; +static CVI_U8 data_ST7796S_16[] = { 0xf0, 0x3c }; +static CVI_U8 data_ST7796S_17[] = { 0xf0, 0x69 }; +static CVI_U8 data_ST7796S_18[] = { 0x21 }; // Display Inversion On +static CVI_U8 data_ST7796S_19[] = { 0x29 }; // Display ON + +const struct dsc_instr dsi_init_cmds_ST7796S_320x480[] = { + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_ST7796S_0 }, + {.delay = 120, .data_type = 0x15, .size = 2, .data = data_ST7796S_1 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ST7796S_2 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ST7796S_3 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ST7796S_4 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ST7796S_5 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ST7796S_6 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_ST7796S_7 }, + {.delay = 0, .data_type = 0x29, .size = 3, .data = data_ST7796S_8 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ST7796S_9 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ST7796S_10 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ST7796S_11 }, + {.delay = 0, .data_type = 0x29, .size = 9, .data = data_ST7796S_12 }, + {.delay = 0, .data_type = 0x29, .size = 15, .data = data_ST7796S_13 }, + {.delay = 0, .data_type = 0x29, .size = 15, .data = data_ST7796S_14 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ST7796S_15 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ST7796S_16 }, + {.delay = 0, .data_type = 0x15, .size = 2, .data = data_ST7796S_17 }, + {.delay = 0, .data_type = 0x05, .size = 1, .data = data_ST7796S_18 }, + {.delay = 120, .data_type = 0x05, .size = 1, .data = data_ST7796S_19 } +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_ST7796S_H_ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_zct2133v1.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_zct2133v1.h new file mode 100644 index 00000000..abee39a2 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/dsi_zct2133v1.h @@ -0,0 +1,75 @@ +#ifndef _MIPI_TX_PARAM_ZCT2133V1_H_ +#define _MIPI_TX_PARAM_ZCT2133V1_H_ + +#ifndef __UBOOT__ +#include +#include +#else +#include +#endif + +#define ZCT2133V1_VACT 1280 +#define ZCT2133V1_VSA 10 +#define ZCT2133V1_VBP 34 +#define ZCT2133V1_VFP 3 + +#define ZCT2133V1_HACT 800 +#define ZCT2133V1_HSA 80 +#define ZCT2133V1_HBP 136 +#define ZCT2133V1_HFP 56 + +#define ZCT_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_zct2133v1_800x1280 = { + .devno = 0, + .lane_id = {MIPI_TX_LANE_0, MIPI_TX_LANE_CLK, MIPI_TX_LANE_1, -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 = ZCT2133V1_HSA, + .vid_hbp_pixels = ZCT2133V1_HBP, + .vid_hfp_pixels = ZCT2133V1_HFP, + .vid_hline_pixels = ZCT2133V1_HACT, + .vid_vsa_lines = ZCT2133V1_VSA, + .vid_vbp_lines = ZCT2133V1_VBP, + .vid_vfp_lines = ZCT2133V1_VFP, + .vid_active_lines = ZCT2133V1_VACT, + .vid_vsa_pos_polarity = true, + .vid_hsa_pos_polarity = false, + }, + .pixel_clk = ZCT_PIXEL_CLK(ZCT2133V1), +}; + +const struct hs_settle_s hs_timing_cfg_zct2133v1_800x1280 = { .prepare = 6, .zero = 32, .trail = 1 }; + +#define CVI_U8 uint8_t + +static CVI_U8 data_zct2133v1_0[] = { 0xE1, 0x93 }; +static CVI_U8 data_zct2133v1_1[] = { 0xE2, 0x65 }; +static CVI_U8 data_zct2133v1_2[] = { 0xE3, 0xF8 }; +static CVI_U8 data_zct2133v1_3[] = { 0x80, 0x01 }; +static CVI_U8 data_zct2133v1_4[] = { 0x11 }; +static CVI_U8 data_zct2133v1_5[] = { 0x29 }; + +// len == 1 , type 0x05 +// len == 2 , type 0x15 or type 23 +// len >= 3 , type 0x29 or type 0x39 +#define TYPE1 0x05 +#define TYPE2 0x15 +#define TYPE3 0x29 + +const struct dsc_instr dsi_init_cmds_zct2133v1_800x1280[] = { + {.delay = 0, .data_type = TYPE2, .size = 2, .data = data_zct2133v1_0 }, + {.delay = 0, .data_type = TYPE2, .size = 2, .data = data_zct2133v1_1 }, + {.delay = 0, .data_type = TYPE2, .size = 2, .data = data_zct2133v1_2 }, + {.delay = 0, .data_type = TYPE2, .size = 2, .data = data_zct2133v1_3 }, + {.delay = 0, .data_type = TYPE1, .size = 1, .data = data_zct2133v1_4 }, + {.delay = 0, .data_type = TYPE1, .size = 1, .data = data_zct2133v1_5 }, +}; + +#else +#error "MIPI_TX_PARAM multi-delcaration!!" +#endif // _MIPI_TX_PARAM_ZCT2133V1_H_ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/hw_mcu_st7789v3.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/hw_mcu_st7789v3.h new file mode 100644 index 00000000..cdd9d3c8 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/hw_mcu_st7789v3.h @@ -0,0 +1,117 @@ +#ifndef _MCU_PARAM_ST7789V_H_ +#define _MCU_PARAM_ST7789V_H_ + +#include + +#define COMMAND 0 +#define DATA 1 + +const struct VO_PINMUX st7789v3_pins_cfg = { + .pin_num = 11, + .d_pins = { + {VO_MIPI_TXM4, VO_MUX_MCU_DATA0}, + {VO_MIPI_TXP4, VO_MUX_MCU_DATA1}, + {VO_MIPI_TXM3, VO_MUX_MCU_DATA2}, + {VO_MIPI_TXP3, VO_MUX_MCU_DATA3}, + {VO_MIPI_TXM2, VO_MUX_MCU_DATA4}, + {VO_MIPI_TXP2, VO_MUX_MCU_DATA5}, + {VO_MIPI_TXM1, VO_MUX_MCU_DATA6}, + {VO_MIPI_TXP1, VO_MUX_MCU_DATA7}, + {VO_MIPI_TXM0, VO_MUX_MCU_RD}, + {VO_MIPI_TXP0, VO_MUX_MCU_WR}, + {VO_VIVO_D10, VO_MUX_MCU_RS}, + } +}; + +const struct VO_MCU_INSTRS st7789v3_instrs = { + .instr_num = 72, + .instr_cmd = { + {.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},//Display Setting + {.delay = 0, .data_type = DATA, .data = (1<<6)/*(1<<5)|(1<<6)*/}, + {.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},//Gamma setting + {.delay = 0, .data_type = DATA, .data = 0xD0}, + {.delay = 0, .data_type = DATA, .data = 0x04}, + {.delay = 0, .data_type = DATA, .data = 0x0C}, + {.delay = 0, .data_type = DATA, .data = 0x0E}, + {.delay = 0, .data_type = DATA, .data = 0x0E}, + {.delay = 0, .data_type = DATA, .data = 0x29}, + {.delay = 0, .data_type = DATA, .data = 0x37}, + {.delay = 0, .data_type = DATA, .data = 0x44}, + {.delay = 0, .data_type = DATA, .data = 0x47}, + {.delay = 0, .data_type = DATA, .data = 0x0B}, + {.delay = 0, .data_type = DATA, .data = 0x17}, + {.delay = 0, .data_type = DATA, .data = 0x16}, + {.delay = 0, .data_type = DATA, .data = 0x1B}, + {.delay = 0, .data_type = DATA, .data = 0x1F}, + {.delay = 0, .data_type = COMMAND, .data = 0xE1}, + {.delay = 0, .data_type = DATA, .data = 0xD0}, + {.delay = 0, .data_type = DATA, .data = 0x04}, + {.delay = 0, .data_type = DATA, .data = 0x0C}, + {.delay = 0, .data_type = DATA, .data = 0x0E}, + {.delay = 0, .data_type = DATA, .data = 0x0F}, + {.delay = 0, .data_type = DATA, .data = 0x29}, + {.delay = 0, .data_type = DATA, .data = 0x37}, + {.delay = 0, .data_type = DATA, .data = 0x44}, + {.delay = 0, .data_type = DATA, .data = 0x4A}, + {.delay = 0, .data_type = DATA, .data = 0x0C}, + {.delay = 0, .data_type = DATA, .data = 0x17}, + {.delay = 0, .data_type = DATA, .data = 0x16}, + {.delay = 0, .data_type = DATA, .data = 0x1B}, + {.delay = 0, .data_type = DATA, .data = 0x1F}, + {.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}, + } +}; + +const VO_HW_MCU_CFG_S st7789v3Cfg = { + .pins = st7789v3_pins_cfg, + .mode = VO_MCU_MODE_RGB565, + .lcd_power_gpio_num = GPIOB_03, + .lcd_power_avtive = GPIO_ACTIVE_HIGH, + .backlight_gpio_num = GPIOA_30, + .backlight_avtive = GPIO_ACTIVE_HIGH, + .reset_gpio_num = GPIOE_13, + .reset_avtive = GPIO_ACTIVE_LOW, + .instrs = st7789v3_instrs, +}; + +#endif // _MCU_PARAM_ST7789V_H_ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/i80_st7789v.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/i80_st7789v.h new file mode 100644 index 00000000..3cd891c6 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/lvds_lcm185x56.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/lvds_lcm185x56.h new file mode 100644 index 00000000..43f32f68 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/component/panel/sg200x/lvds_lcm185x56.h @@ -0,0 +1,15 @@ +#ifndef _LVDS_PARAM_LCM185X56_H_ +#define _LVDS_PARAM_LCM185X56_H_ + +#include + +const VO_LVDS_ATTR_S lvds_lcm185x56_cfg = { + .lvds_vesa_mode = VO_LVDS_MODE_JEIDA, + .out_bits = VO_LVDS_OUT_8BIT, + .chn_num = 1, + .data_big_endian = 0, + .lane_id = {VO_LVDS_LANE_0, VO_LVDS_LANE_1, VO_LVDS_LANE_CLK, VO_LVDS_LANE_2, VO_LVDS_LANE_3}, + .lane_pn_swap = {false, false, false, false, false}, +}; + +#endif // _LVDS_PARAM_LCM185X56_H_ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/acodec.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/acodec.h new file mode 100644 index 00000000..c5422643 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/acodec.h @@ -0,0 +1,177 @@ +/* + * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. + * + * File Name: include/acodec.h + * Description: audio codec define and api + */ +#ifndef _ACODEC_H_ +#define _ACODEC_H_ + +#define IOC_TYPE_ACODEC 'A' + +typedef enum cviACODEC_FS_E { + ACODEC_FS_8000 = 0x1, + ACODEC_FS_11025 = 0x2, + ACODEC_FS_12000 = 0x3, + ACODEC_FS_16000 = 0x4, + ACODEC_FS_22050 = 0x5, + ACODEC_FS_24000 = 0x6, + ACODEC_FS_32000 = 0x7, + ACODEC_FS_44100 = 0x8, + ACODEC_FS_48000 = 0x9, + ACODEC_FS_64000 = 0xa, + ACODEC_FS_96000 = 0xb, + + ACODEC_FS_BUTT = 0x1c, +} ACODEC_FS_E; + +typedef enum cviACODEC_MIXER_E { + ACODEC_MIXER_IN0 = 0x0, /* 16CV500/16DV300 Unsupport IN0. */ + ACODEC_MIXER_IN1 = 0x1, + ACODEC_MIXER_IN_D = 0x2, + + ACODEC_MIXER_BUTT, +} ACODEC_MIXER_E; + +typedef struct { + /*volume control, 0x00~0x7e, 0x7F:mute*/ + unsigned int vol_ctrl; + /*adc/dac mute control, 1:mute, 0:unmute*/ + unsigned int vol_ctrl_mute; +} ACODEC_VOL_CTRL; + +typedef enum cviACODEC_IOCTL_E { + IOC_NR_SOFT_RESET_CTRL = 0x0, + + IOC_NR_SET_INPUT_VOL, + IOC_NR_SET_OUTPUT_VOL, + IOC_NR_GET_INPUT_VOL, + IOC_NR_GET_OUTPUT_VOL, + + IOC_NR_SET_I2S1_FS, + IOC_NR_SET_MIXER_MIC, + IOC_NR_SEL_DAC_CLK, + IOC_NR_SEL_ADC_CLK, + IOC_NR_SEL_ANA_MCLK, + IOC_NR_SET_GAIN_MICL, + IOC_NR_SET_GAIN_MICR, + IOC_NR_SET_DACL_VOL, + IOC_NR_SET_DACR_VOL, + IOC_NR_SET_ADCL_VOL, + IOC_NR_SET_ADCR_VOL, + IOC_NR_SET_MICL_MUTE, + IOC_NR_SET_MICR_MUTE, + IOC_NR_SET_DACL_MUTE, + IOC_NR_SET_DACR_MUTE, + IOC_NR_BOOSTL_ENABLE, + IOC_NR_BOOSTR_ENABLE, + + IOC_NR_GET_GAIN_MICL, + IOC_NR_GET_GAIN_MICR, + IOC_NR_GET_DACL_VOL, + IOC_NR_GET_DACR_VOL, + IOC_NR_GET_ADCL_VOL, + IOC_NR_GET_ADCR_VOL, + + IOC_NR_SET_PD_DACL, + IOC_NR_SET_PD_DACR, + IOC_NR_SET_PD_ADCL, + IOC_NR_SET_PD_ADCR, + IOC_NR_SET_PD_LINEINL, + IOC_NR_SET_PD_LINEINR, + + IOC_NR_SET_DAC_DE_EMPHASIS, + IOC_NR_SET_ADC_HP_FILTER, + + IOC_NR_SET_I2S1_DATAWIDTH, +} ACODEC_IOCTL_E; + +/*reset the audio code to the default config*/ +#define ACODEC_SOFT_RESET_CTRL \ + _IO(IOC_TYPE_ACODEC, IOC_NR_SOFT_RESET_CTRL) +/*ACODEC_FS_E*/ +#define ACODEC_SET_I2S1_FS \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_I2S1_FS, unsigned int) + +/*select the micpga's input, micin linein, or differential input(ACODEC_MIXER_E)*/ +#define ACODEC_SET_MIXER_MIC \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_MIXER_MIC, unsigned int) +/*analog part input volume control(left channel 0~0x1f)*/ +#define ACODEC_SET_GAIN_MICL \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_GAIN_MICL, unsigned int) +/*analog part input volume control(right channel 0~0x1f)*/ +#define ACODEC_SET_GAIN_MICR \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_GAIN_MICR, unsigned int) +/*Output volume control(left channel) ACODEC_VOL_CTRL*/ +#define ACODEC_SET_DACL_VOL \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_DACL_VOL, ACODEC_VOL_CTRL) +/*Output volume control(right channel) ACODEC_VOL_CTRL*/ +#define ACODEC_SET_DACR_VOL \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_DACR_VOL, ACODEC_VOL_CTRL) +/*Input volume control(left channel) ACODEC_VOL_CTRL*/ +#define ACODEC_SET_ADCL_VOL \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_ADCL_VOL, ACODEC_VOL_CTRL) +/*Input volume control(right channel) ACODEC_VOL_CTRL*/ +#define ACODEC_SET_ADCR_VOL \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_ADCR_VOL, ACODEC_VOL_CTRL) +/*Input mute control(left channel), 1:mute, 0:unmute*/ +#define ACODEC_SET_MICL_MUTE \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_MICL_MUTE, unsigned int) +/*Input mute control(right channel), 1:mute, 0:unmute*/ +#define ACODEC_SET_MICR_MUTE \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_MICR_MUTE, unsigned int) +/*Output mute control(left channel), 1:mute, 0:unmute*/ +#define ACODEC_SET_DACL_MUTE \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_DACL_MUTE, unsigned int) +/*Output mute control(right channel), 1:mute, 0:unmute*/ +#define ACODEC_SET_DACR_MUTE \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_DACR_MUTE, unsigned int) +#define ACODEC_GET_GAIN_MICL \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_GET_GAIN_MICL, unsigned int) +#define ACODEC_GET_GAIN_MICR \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_GET_GAIN_MICR, unsigned int) +#define ACODEC_GET_DACL_VOL \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_GET_DACL_VOL, ACODEC_VOL_CTRL) +#define ACODEC_GET_DACR_VOL \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_GET_DACR_VOL, ACODEC_VOL_CTRL) +#define ACODEC_GET_ADCL_VOL \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_GET_ADCL_VOL, ACODEC_VOL_CTRL) +#define ACODEC_GET_ADCR_VOL \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_GET_ADCR_VOL, ACODEC_VOL_CTRL) + +/*set adcl power, 0: power up, 1: power down*/ +#define ACODEC_SET_PD_DACL \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_PD_DACL, unsigned int) +/*set adcr power, 0: power up, 1: power down*/ +#define ACODEC_SET_PD_DACR \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_PD_DACR, unsigned int) +/*set adcl power, 0: power up, 1: power down*/ +#define ACODEC_SET_PD_ADCL \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_PD_ADCL, unsigned int) +/*set adcr power, 0: power up, 1: power down*/ +#define ACODEC_SET_PD_ADCR \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_PD_ADCR, unsigned int) +/*set adcl power, 0: power up, 1: power down*/ +#define ACODEC_SET_PD_LINEINL \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_PD_LINEINL, unsigned int) +/*set adcr power, 0: power up, 1: power down*/ +#define ACODEC_SET_PD_LINEINR \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_PD_LINEINR, unsigned int) + +/* Don't need to set, the driver will set a default value */ +/*clock of dac and adc is reverse or obverse*/ +#define ACODEC_SET_DAC_DE_EMPHASIS \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_DAC_DE_EMPHASIS, unsigned int) +#define ACODEC_SET_ADC_HP_FILTER \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_ADC_HP_FILTER, unsigned int) + +#define ACODEC_SET_INPUT_VOL \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_INPUT_VOL, unsigned int) +#define ACODEC_SET_OUTPUT_VOL \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_SET_OUTPUT_VOL, unsigned int) +#define ACODEC_GET_INPUT_VOL \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_GET_INPUT_VOL, unsigned int) +#define ACODEC_GET_OUTPUT_VOL \ + _IOWR(IOC_TYPE_ACODEC, IOC_NR_GET_OUTPUT_VOL, unsigned int) + +#endif /* End of #ifndef _ACODEC_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_audio.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_audio.h new file mode 100644 index 00000000..c065c8cb --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_audio.h @@ -0,0 +1,587 @@ +/* + * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. + * + * File Name: include/cvi_audio.h + * Description: basic audio api for application layer + */ + +#ifndef __CVI_AUDIO_H__ +#define __CVI_AUDIO_H__ + +#include +#include +#include +#include +#include +#include + +#include "cvi_comm_aio.h" +#include "cvi_comm_aenc.h" +#include "cvi_comm_adec.h" +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" +{ +#endif +#endif /* __cplusplus */ + +#define AENC_ADAPT_MAGIC 0Xfcfcfcfc +#ifdef CVI_MODIFIED +CVI_S32 CVI_AUDIO_DEBUG(void); +#endif +//define print level -------------------------------------[start] +#define CVI_AUD_MASK_ERR (0x00) +#define CVI_AUD_MASK_INFO (0x01) +#define CVI_AUD_MASK_DBG (0x02) + +/* =====Audio function api===== */ + +/** + * @brief Audio init + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AUDIO_INIT(void); + +/** + * @brief Audio deinit + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AUDIO_DEINIT(void); + +/** + * @brief Set the binding properties of the audio + * @param pstSrcChn Source information of bind mode + * @param pstDestChn Target information of bind mode + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AUD_SYS_Bind(const MMF_CHN_S *pstSrcChn, const MMF_CHN_S *pstDestChn); + +/** + * @brief Unregister the binding mode of the system + * @param pstSrcChn Source information of bind mode + * @param pstDestChn Target information of bind mode + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AUD_SYS_UnBind(const MMF_CHN_S *pstSrcChn, const MMF_CHN_S *pstDestChn); +/* AI function api. */ + +/** + * @brief Set the parameter to audio + * @param AiDevId the number of audio device + * @param pstAttr pointer that describes an ai property + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_SetPubAttr(AUDIO_DEV AiDevId, const AIO_ATTR_S *pstAttr); + +/** + * @brief Get the parameter to audio + * @param AiDevId the number of audio device + * @param pstAttr pointer that describes an ai property + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_GetPubAttr(AUDIO_DEV AiDevId, AIO_ATTR_S *pstAttr); + +/** + * @brief Create and initial ai device. + * @param AiDevId the number of audio device + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_Enable(AUDIO_DEV AiDevId); + +/** + * @brief Destroy ai device + * @param AiDevId the number of audio device + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_Disable(AUDIO_DEV AiDevId); + +/** + * @brief Create and initial ai channel. + * @param AiDevId the number of audio device + * @param AiChn the number of audio channels + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_EnableChn(AUDIO_DEV AiDevId, AI_CHN AiChn); + +/** + * @brief Destroy ai channels + * @param AiDevId the number of audio device + * @param AiChn the number of audio channels + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_DisableChn(AUDIO_DEV AiDevId, AI_CHN AiChn); + +/** + * @brief Record and get audio data + * @param AiDevId the number of audio device + * @param AiChn the number of audio channels + * @param pstFrm the starting address of the obtained audio data + * @param pstAecFrm the starting address of the obtained Reference signal + * @param s32MilliSec -1:block mode/0:non-blocking/s32MilliSec + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_GetFrame(AUDIO_DEV AiDevId, AI_CHN AiChn, + AUDIO_FRAME_S *pstFrm, AEC_FRAME_S *pstAecFrm, CVI_S32 s32MilliSec); + +/** + * @brief Release record frame + * @param AiDevId the number of audio device + * @param AiChn the number of audio channels + * @param pstFrm the starting address of the obtained audio data + * @param pstAecFrm the starting address of the obtained Reference signal + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_ReleaseFrame(AUDIO_DEV AiDevId, AI_CHN AiChn, + const AUDIO_FRAME_S *pstFrm, const AEC_FRAME_S *pstAecFrm); + +/** + * @brief Sets the frame depth of audio data + * @param AiDevId the number of audio device + * @param AiChn the number of audio channels + * @param pstChnParam frame depth struct + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_SetChnParam(AUDIO_DEV AiDevId, AI_CHN AiChn, + const AI_CHN_PARAM_S *pstChnParam); +/** + * @brief Get the frame depth of audio data + * @param AiDevId the number of audio device + * @param AiChn the number of audio channels + * @param pstChnParam frame depth struct + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_GetChnParam(AUDIO_DEV AiDevId, AI_CHN AiChn, + AI_CHN_PARAM_S *pstChnParam); +/** + * @brief Set record volume + * @param AiDevId the number of audio device + * @param s32VolumeStep input gain + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_SetVolume(AUDIO_DEV AiDevId, CVI_S32 s32VolumeStep); + +/** + * @brief Get record volume + * @param AiDevId the number of audio device + * @param ps32VolumeStep pointer to s32VolumeStep that indicates ai gain + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_GetVolume(AUDIO_DEV AiDevId, CVI_S32 *ps32VolumeStep); +/** + * @brief Set record volume + * @param AiDevId the number of audio device + * @param AiChn the number of audio channels + * @param s32VolumeDb input gain [0-100] + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_SetVqeVolume(AUDIO_DEV AiDevId, AI_CHN AiChn, CVI_S32 s32VolumeDb); +/** + * @brief Get record volume + * @param AiDevId the number of audio device + * @param AiChn the number of audio channels + * @param ps32VolumeDb pointer to s32VolumeStep that indicates ai gain + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_GetVqeVolume(AUDIO_DEV AiDevId, AI_CHN AiChn, CVI_S32 *ps32VolumeDb); +/** + * @brief Start Vqe(AGC+ANR+AES+AEC) + * @param AiDevId the number of audio device + * @param AiChn the number of audio channels + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_EnableVqe(AUDIO_DEV AiDevId, AI_CHN AiChn); + +/** + * @brief Destroy Vqe(AGC+ANR+AES+AEC) + * @param AiDevId the number of audio device + * @param AiChn the number of audio channels + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_DisableVqe(AUDIO_DEV AiDevId, AI_CHN AiChn); + +/** + * @brief Config Vqe(AGC+ANR+AES+AEC) + * @param AiDevId the number of audio device + * @param AiChn the number of audio channels + * @param u32Mask Select mask for vqe function + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_VqeFunConfig(AUDIO_DEV AiDevId, AI_CHN AiChn, int u32Mask); +/** + * @brief Start resample + * @param AiDevId the number of audio device + * @param AiChn the number of audio channels + * @param enOutSampleRate target sample rate + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_EnableReSmp(AUDIO_DEV AiDevId, AI_CHN AiChn, + AUDIO_SAMPLE_RATE_E enOutSampleRate); +/** + * @brief Destroy resample + * @param AiDevId the number of audio device + * @param AiChn the number of audio channels + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_DisableReSmp(AUDIO_DEV AiDevId, AI_CHN AiChn); + +/** + * @brief Set audio input track status + * @param AiDevId the number of audio device + * @param enTrackMode the mode of track + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_SetTrackMode(AUDIO_DEV AiDevId, + AUDIO_TRACK_MODE_E enTrackMode); +/** + * @brief Get audio input track status + * @param AiDevId the number of audio device + * @param penTrackMode the mode of track + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_GetTrackMode(AUDIO_DEV AiDevId, + AUDIO_TRACK_MODE_E *penTrackMode); + + +/** + * @brief Empty the parameters + * @param AiDevId the number of audio device + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_ClrPubAttr(AUDIO_DEV AiDevId); + +/** + * @brief Set vqe attr and enable talk vqe + * @param AiDevId the number of input device + * @param AiChn the number of input channels + * @param AoDevId the number of output device + * @param AoChn the number of output channels + * @param pstVqeConfig the config of vqe + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_SetTalkVqeAttr(AUDIO_DEV AiDevId, AI_CHN AiChn, + AUDIO_DEV AoDevId, AO_CHN AoChn, const AI_TALKVQE_CONFIG_S *pstVqeConfig); + +/** + * @brief Get vqe attr + * @param AiDevId the number of audio device + * @param AiChn the number of audio channels + * @param pstVqeConfig the config of vqe + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AI_GetTalkVqeAttr(AUDIO_DEV AiDevId, AI_CHN AiChn, + AI_TALKVQE_CONFIG_S *pstVqeConfig); + +/* AO function api. */ + +/** + * @brief Transfer data bitdepth + * @param InPt input buffer addr + * @param pu32InSizeByte input buffer size + * @param OutPt output buffer addr + * @param pu32OutSizeByte output buffer size + * @param s32BitOut target bitdepth to transfer only support 24 bit / 32 bit + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_BitOut_Transfer(CVI_CHAR **InPt, CVI_U32 *pu32InSizeByte, + CVI_CHAR **OutPt, + CVI_U32 *pu32OutSizeByte, CVI_S32 s32BitOut); +/** + * @brief Set the parameter to audio output + * @param AoDevId the number of output device + * @param pstAttr pointer that describes an ao property + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_SetPubAttr(AUDIO_DEV AoDevId, const AIO_ATTR_S *pstAttr); + +/** + * @brief Get the parameter to audio output + * @param AoDevId the number of output device + * @param pstAttr pointer that describes an ao property + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_GetPubAttr(AUDIO_DEV AoDevId, AIO_ATTR_S *pstAttr); + +/** + * @brief Create and initial ao device. + * @param AoDevId the number of output device + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_Enable(AUDIO_DEV AoDevId); +/** + * @brief Destroy ao device + * @param AoDevId the number of output device + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_Disable(AUDIO_DEV AoDevId); +/** + * @brief Create and initial ao channel. + * @param AoDevId the number of ao device + * @param AoChn the number of audio channels + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_EnableChn(AUDIO_DEV AoDevId, AO_CHN AoChn); +/** + * @brief Destroy ao channels + * @param AoDevId the number of output device + * @param AoChn the number of output channels + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_DisableChn(AUDIO_DEV AoDevId, AO_CHN AoChn); + +/** + * @brief aplay and send audio data + * @param AoDevId the number of output device + * @param AoChn the number of output channels + * @param pstData the address of data that you want to send + * @param s32MilliSec -1:block mode/0:non-blocking/s32MilliSec + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_SendFrame(AUDIO_DEV AoDevId, AO_CHN AoChn, + const AUDIO_FRAME_S *pstData, CVI_S32 s32MilliSec); + +/** + * @brief Start resample + * @param AoDevId the number of output device + * @param AoDevId the number of output channels + * @param enInSampleRate input sample rate + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_EnableReSmp(AUDIO_DEV AoDevId, AO_CHN AoChn, + AUDIO_SAMPLE_RATE_E enInSampleRate); +/** + * @brief Destroy resample + * @param AoDevId the number of output device + * @param AoChn the number of output channels + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_DisableReSmp(AUDIO_DEV AoDevId, AO_CHN AoChn); +/** + * @brief Clear channel data + * @param AoDevId the number of output device + * @param AoChn the number of output channels + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_ClearChnBuf(AUDIO_DEV AoDevId, AO_CHN AoChn); +/** + * @brief Gets the current status of the AO channel + * @param AoDevId the number of output device + * @param AoChn the number of output channels + * @param pstStatus structure that describes the state of a channel + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_QueryChnStat(AUDIO_DEV AoDevId, AO_CHN AoChn, + AO_CHN_STATE_S *pstStatus); +/** + * @brief Pause send data + * @param AoDevId the number of output device + * @param AoChn the number of output channels + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_PauseChn(AUDIO_DEV AoDevId, AO_CHN AoChn); +/** + * @brief Recovery of transmitted data + * @param AoDevId the number of output device + * @param AoChn the number of output channels + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_ResumeChn(AUDIO_DEV AoDevId, AO_CHN AoChn); +/** + * @brief Set aplay volume + * @param AoDevId the number of output device + * @param s32VolumeDb output gain + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_SetVolume(AUDIO_DEV AoDevId, CVI_S32 s32VolumeDb); +/** + * @brief Get aplay volume + * @param AoDevId the number of output device + * @param ps32VolumeDb pointer to s32VolumeDb that indicates ao gain + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_GetVolume(AUDIO_DEV AoDevId, CVI_S32 *ps32VolumeDb); +/** + * @brief Set ao mute + * @param AoDevId the number of output device + * @param bEnable Select whether to enable mute mode + * @param pstFade structure that describes fadein and fadeout + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_SetMute(AUDIO_DEV AoDevId, CVI_BOOL bEnable, + const AUDIO_FADE_S *pstFade); +/** + * @brief Get ao mute status + * @param AoDevId the number of output device + * @param bEnable Select whether to enable mute mode + * @param pstFade structure that describes fadein and fadeout + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_GetMute(AUDIO_DEV AoDevId, CVI_BOOL *pbEnable, + AUDIO_FADE_S *pstFade); +/** + * @brief Set audio output track status + * @param AoDevId the number of output device + * @param enTrackMode the mode of track + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_SetTrackMode(AUDIO_DEV AoDevId, + AUDIO_TRACK_MODE_E enTrackMode); +/** + * @brief Get audio output track status + * @param AoDevId the number of output device + * @param penTrackMode the mode of track + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AO_GetTrackMode(AUDIO_DEV AoDevId, + AUDIO_TRACK_MODE_E *penTrackMode); + +/* AENC function api. */ +/** + * @brief Enable and create channel to encode + * @param AeChn the number of aenc channel + * @param pstAttr pointer that describes an aenc property + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AENC_CreateChn(AENC_CHN AeChn, const AENC_CHN_ATTR_S *pstAttr); +/** + * @brief Destroy aenc channel + * @param AeChn the number of aenc channel + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AENC_DestroyChn(AENC_CHN AeChn); +/** + * @brief Send audio data to channel + * @param AeChn the number of aenc channel + * @param pstFrm data that you want to send + * @param pstAecFrm Reference signal + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AENC_SendFrame(AENC_CHN AeChn, const AUDIO_FRAME_S *pstFrm, + const AEC_FRAME_S *pstAecFrm); +/** + * @brief Encode pcm and get data + * @param AeChn the number of aenc channel + * @param pstStream data that you get + * @param s32MilliSec -1:block mode/0:non-blocking/s32MilliSec + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AENC_GetStream(AENC_CHN AeChn, AUDIO_STREAM_S *pstStream, + CVI_S32 s32MilliSec); +/** + * @brief Release aenc stream + * @param AeChn the number of aenc channel + * @param pstStream the information obtained by calling CVI_AENC_GetStream + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AENC_ReleaseStream(AENC_CHN AeChn, + const AUDIO_STREAM_S *pstStream); + + +/** + * @brief Get aenc channel data len and EncInBuff + * @param AeChn the number of aenc channel + * @param pu64PhysAddr the address of EncInBuff + * @param pu32Size data len in aenc channel + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AENC_GetStreamBufInfo(AENC_CHN AeChn, CVI_U64 *pu64PhysAddr, + CVI_U32 *pu32Size); + +/** + * @brief Registered AAC encoder + * Please using api:CVI_MPI_AENC_AacInit instead + * @param ps32Handle aenc handle + * @param pstEncoder Registered encode api + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AENC_RegisterExternalEncoder(CVI_S32 *ps32Handle, const AAC_AENC_ENCODER_S *pstEncoder); + +/** + * @brief Unregistered AAC encoder + * Please using api:CVI_MPI_AENC_AacDeInit instead + * @param ps32Handle aenc handle + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_AENC_UnRegisterExternalEncoder(CVI_S32 s32Handle); + +/* ADEC function api. */ +/** + * @brief Enable and create channel to decode + * @param AdChn the number of adec channel + * @param pstAttr pointer that describes an adec property + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_ADEC_CreateChn(ADEC_CHN AdChn, const ADEC_CHN_ATTR_S *pstAttr); +/** + * @brief Destroy adec channel + * @param AdChn the number of adec channel + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_ADEC_DestroyChn(ADEC_CHN AdChn); + +/** + * @brief Send audio data to channel + * @param AdChn the number of adec channel + * @param pstStream data that you want to send + * @param bBlock Select whether to block + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_ADEC_SendStream(ADEC_CHN AdChn, const AUDIO_STREAM_S *pstStream, + CVI_BOOL bBlock); + +/** + * @brief Clear channel data + * @param AdChn the number of adec channel + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_ADEC_ClearChnBuf(ADEC_CHN AdChn); + +/** + * @brief Registered AAC decoder + * Please using api:CVI_MPI_ADEC_AacInit instead + * @param ps32Handle adec handle + * @param pstDecoder Registered decoder api + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_ADEC_RegisterExternalDecoder(CVI_S32 *ps32Handle, + const ADEC_DECODER_S *pstDecoder); +/** + * @brief Unregistered AAC decoder + * Please using api:CVI_MPI_ADEC_AacDeInit instead + * @param s32Handle adec handle + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_ADEC_UnRegisterExternalDecoder(CVI_S32 s32Handle); +/** + * @brief Decode pcm and get data + * @param AdChn the number of adec channel + * @param pstFrmInfo data that you get + * @param bBlock Select whether to block + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_ADEC_GetFrame(ADEC_CHN AdChn, AUDIO_FRAME_INFO_S *pstFrmInfo, + CVI_BOOL bBlock); + +/** + * @brief Clear channel buffer + * @param pstFrmInfo data that you get + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_ADEC_ReleaseFrame(ADEC_CHN AdChn, const AUDIO_FRAME_INFO_S *pstFrmInfo); + +/** + * @brief Send end flag to Decoder + * @param AdChn the number of adec channel + * @param bInstant end flag + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_ADEC_SendEndOfStream(ADEC_CHN AdChn, CVI_BOOL bInstant); +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* __CVI_AUDIO_H__ */ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_bin.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_bin.h new file mode 100644 index 00000000..ee9c31e8 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_bin.h @@ -0,0 +1,156 @@ +#ifndef __CVI_BIN_H__ +#define __CVI_BIN_H__ + + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#include "stdio.h" +#include +#include + +// ++++++++ If you want to change these interfaces, please contact the isp team. ++++++++ +#define BIN_FILE_LENGTH 256 + +#define CVI_BIN_NULL_POINT 0xCB000001 +#define CVI_BIN_REG_ATTR_ERR 0xCB000002 +#define CVI_BIN_MALLOC_ERR 0xCB000003 +#define CVI_BIN_CHIP_ERR 0xCB000004 +#define CVI_BIN_CRC_ERR 0xCB000005 +#define CVI_BIN_SIZE_ERR 0xCB000006 /*size of inputing data is error.*/ +#define CVI_BIN_LEBLE_ERR 0xCB000007 +#define CVI_BIN_DATA_ERR 0xCB000008 /*data abnormal*/ +#define CVI_BIN_SECURITY_SOLUTION_FAILED 0xCB00000A +#define CVI_BIN_COMPRESS_ERROR 0xCB00000B /*json compress buffer fail.*/ +#define CVI_BIN_UNCOMPRESS_ERROR 0xCB00000C /*json uncompress fail.*/ +#define CVI_BIN_SAPCE_ERR 0xCB00000D /*Input buffer space isn't enough.*/ +#define CVI_BIN_JSON_ERR 0xCB00000E /*json is inexistence in current bin file.*/ +#define CVI_BIN_UPDATE_ERROR 0xCB00000F /*Update bin para fail automatically*/ +#define CVI_BIN_FINDBINFILE_ERROR 0xCB000010 /*can't find bin file*/ +#define CVI_BIN_NOJSON_ERROR 0xCB000011 /*invalid json in current bin file*/ +#define CVI_BIN_JSONHANLE_ERROR 0xCB000012 /*creat json handle fail*/ +#define CVI_BIN_ID_ERROR 0xCB000013 /*invalid id error*/ +#define CVI_BIN_READ_ERROR 0xCB000014 /*read para from file fail*/ +#define CVI_BIN_FILE_ERROR 0xCB000015 /*PQbin file is invalid.*/ +#define CVI_BIN_SENSORNUM_ERROR 0xCB000016 /*Sensor number exceeds specified sensor number in the current bin file.*/ + +enum CVI_BIN_SECTION_ID { + CVI_BIN_ID_MIN = 0, + CVI_BIN_ID_HEADER = CVI_BIN_ID_MIN, + CVI_BIN_ID_ISP0, + CVI_BIN_ID_ISP1, + CVI_BIN_ID_ISP2, + CVI_BIN_ID_ISP3, + CVI_BIN_ID_VPSS, + CVI_BIN_ID_VDEC, + CVI_BIN_ID_VENC, + CVI_BIN_ID_VO, + CVI_BIN_ID_MAX +}; + +enum CVI_BIN_CREATMODE { + CVI_BIN_AUTO = 0, + CVI_BIN_MANUAL, + CVI_BIN_MODE_MAX +}; + +typedef struct { + CVI_UCHAR Author[32]; + CVI_UCHAR Desc[1024]; + CVI_UCHAR Time[32]; +} CVI_BIN_EXTRA_S; + +typedef struct { + CVI_U32 u32InitSize; + CVI_U32 u32CompreSize; +} CVI_JSON_INFO; + +typedef struct _CVI_JSON_HEADER { + CVI_JSON_INFO size[CVI_BIN_ID_MAX]; +} CVI_JSON_HEADER; + +typedef struct _CVI_BIN_HEADER { + CVI_U32 chipId; + CVI_BIN_EXTRA_S extraInfo; + CVI_U32 size[CVI_BIN_ID_MAX]; +} CVI_BIN_HEADER; + +CVI_S32 CVI_BIN_GetBinExtraAttr(FILE *fp, CVI_BIN_EXTRA_S *extraInfo); +CVI_S32 CVI_BIN_SaveParamToBin(FILE *fp, CVI_BIN_EXTRA_S *extraInfo); +CVI_S32 CVI_BIN_LoadParamFromBin(enum CVI_BIN_SECTION_ID id, CVI_U8 *buf); +CVI_S32 CVI_BIN_SetBinName(WDR_MODE_E wdrMode, const CVI_CHAR *binName); +CVI_S32 CVI_BIN_GetBinName(CVI_CHAR *binName); + +/* CVI_BIN_LoadParamFromBinEx: + * get bin data from buffer + * + * [in] buf: input buf + * u32DataLength:length of bin data + * [Out]void + * return: please refer to CVI_BIN_ImportBinData + */ +CVI_S32 CVI_BIN_LoadParamFromBinEx(enum CVI_BIN_SECTION_ID id, CVI_U8 *buf, CVI_U32 u32DataLength); +/* CVI_BIN_GetBinTotalLen: + * Get length of bin data + * + * [in]void + * [Out]void + * return: length of bin data + */ +CVI_U32 CVI_BIN_GetBinTotalLen(void); +/* CVI_BIN_ExportBinData: + * get bin data from buffer + * + * [in] pu8Buffer:save bin data + * u32DataLength:length of bin data + * [Out]void. + * return: 0: Success; + * error codes: + * 0xCB000001:input pointer is null. + * 0xCB000003: malloc fail. + * 0xCB000008: data error. + * 0xCB00000A: security solution fail. + * 0xCB00000B: json compress fail. + * 0xCB00000D: Input buffer space isn't enough. + * 0xCB000012: creat json handle fail. + * 0xCB000013: invalid id error. + */ +CVI_S32 CVI_BIN_ExportBinData(CVI_U8 *pu8Buffer, CVI_U32 u32DataLength); +/* CVI_BIN_ImportBinData: + * set bin data from buffer + * + * [in] pu8Buffer:save bin data + * u32DataLength:length of bin data + * [Out]void + * return: 0: Success; + * error codes: + * 0xCB000001: input pointer is null. + * 0xCB000003: malloc fail. + * 0xCB000006: size of inputing data is error. + * 0xCB000008: data error. + * 0xCB00000C: json uncompress fail. + * 0xCB00000E: json inexistence fail. + * 0xCB00000F: update bin para from json fail automatically. + * 0xCB000010: can't find bin file. + * 0xCB000011: invalid json in current bin file. + * 0xCB000012: creat json handle fail. + * 0xCB000013: invalid id error. + * 0xCB000014: read para from file fail. + * 0xCB000015: current PQbin file is invalid. + * 0xCB000016: Sensor number exceeds specified sensor number in bin file. + */ +CVI_S32 CVI_BIN_ImportBinData(CVI_U8 *pu8Buffer, CVI_U32 u32DataLength); +// -------- If you want to change these interfaces, please contact the isp team. -------- + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif + + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_buffer.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_buffer.h new file mode 100644 index 00000000..20698c9d --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_buffer.h @@ -0,0 +1,334 @@ +/* + * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. + * + * File Name: include/cvi_buffer.h + * Description: + * The count defination of buffer size + */ + +#ifndef __CVI_BUFFER_H__ +#define __CVI_BUFFER_H__ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#include +#include +#include +#include +#include +#include + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +#define CV183X_WA_FMT(x) (((x) == PIXEL_FORMAT_YUV_PLANAR_420) || ((x) == PIXEL_FORMAT_YUV_PLANAR_422) || \ + ((x) == PIXEL_FORMAT_YUV_PLANAR_444) || ((x) == PIXEL_FORMAT_RGB_888_PLANAR) || \ + ((x) == PIXEL_FORMAT_BGR_888_PLANAR) || ((x) == PIXEL_FORMAT_HSV_888_PLANAR)) + +static inline CVI_VOID COMMON_GetPicBufferConfig(CVI_U32 u32Width, CVI_U32 u32Height, + PIXEL_FORMAT_E enPixelFormat, DATA_BITWIDTH_E enBitWidth, + COMPRESS_MODE_E enCmpMode, CVI_U32 u32Align, VB_CAL_CONFIG_S *pstCalConfig) +{ + CVI_U8 u8BitWidth = 0; + CVI_U32 u32VBSize = 0; + CVI_U32 u32AlignHeight = 0; + CVI_U32 u32MainStride = 0; + CVI_U32 u32CStride = 0; + CVI_U32 u32MainSize = 0; + CVI_U32 u32YSize = 0; + CVI_U32 u32CSize = 0; + + /* u32Align: 0 is automatic mode, alignment size following system. Non-0 for specified alignment size */ + if (u32Align == 0) + u32Align = DEFAULT_ALIGN; + else if (u32Align > MAX_ALIGN) + u32Align = MAX_ALIGN; + else + u32Align = (ALIGN(u32Align, DEFAULT_ALIGN)); + + switch (enBitWidth) { + case DATA_BITWIDTH_8: { + u8BitWidth = 8; + break; + } + case DATA_BITWIDTH_10: { + u8BitWidth = 10; + break; + } + case DATA_BITWIDTH_12: { + u8BitWidth = 12; + break; + } + case DATA_BITWIDTH_14: { + u8BitWidth = 14; + break; + } + case DATA_BITWIDTH_16: { + u8BitWidth = 16; + break; + } + default: { + u8BitWidth = 0; + break; + } + } + + if ((enPixelFormat == PIXEL_FORMAT_YUV_PLANAR_420) + || (enPixelFormat == PIXEL_FORMAT_NV12) + || (enPixelFormat == PIXEL_FORMAT_NV21)) { + u32AlignHeight = ALIGN(u32Height, 2); + } else + u32AlignHeight = u32Height; + + if (enCmpMode == COMPRESS_MODE_NONE) { + u32MainStride = ALIGN((u32Width * u8BitWidth + 7) >> 3, u32Align); + u32YSize = u32MainStride * u32AlignHeight; + + if (enPixelFormat == PIXEL_FORMAT_YUV_PLANAR_420) { + u32CStride = ALIGN(((u32Width >> 1) * u8BitWidth + 7) >> 3, u32Align); + u32CSize = (u32CStride * u32AlignHeight) >> 1; + + u32MainStride = u32CStride * 2; + u32YSize = u32MainStride * u32AlignHeight; + u32MainSize = u32YSize + (u32CSize << 1); + pstCalConfig->plane_num = 3; + } else if (enPixelFormat == PIXEL_FORMAT_YUV_PLANAR_422) { + u32CStride = ALIGN(((u32Width >> 1) * u8BitWidth + 7) >> 3, u32Align); + u32CSize = u32CStride * u32AlignHeight; + + u32MainSize = u32YSize + (u32CSize << 1); + pstCalConfig->plane_num = 3; + } else if (enPixelFormat == PIXEL_FORMAT_RGB_888_PLANAR || + enPixelFormat == PIXEL_FORMAT_BGR_888_PLANAR || + enPixelFormat == PIXEL_FORMAT_HSV_888_PLANAR || + enPixelFormat == PIXEL_FORMAT_YUV_PLANAR_444) { + u32CStride = u32MainStride; + u32CSize = u32YSize; + + u32MainSize = u32YSize + (u32CSize << 1); + pstCalConfig->plane_num = 3; + } else if (enPixelFormat == PIXEL_FORMAT_RGB_BAYER_12BPP) { + u32MainSize = u32YSize; + pstCalConfig->plane_num = 1; + } else if (enPixelFormat == PIXEL_FORMAT_YUV_400) { + u32MainSize = u32YSize; + pstCalConfig->plane_num = 1; + } else if (enPixelFormat == PIXEL_FORMAT_NV12 || enPixelFormat == PIXEL_FORMAT_NV21) { + u32CStride = ALIGN((u32Width * u8BitWidth + 7) >> 3, u32Align); + u32CSize = (u32CStride * u32AlignHeight) >> 1; + + u32MainSize = u32YSize + u32CSize; + pstCalConfig->plane_num = 2; + } else if (enPixelFormat == PIXEL_FORMAT_NV16 || enPixelFormat == PIXEL_FORMAT_NV61) { + u32CStride = ALIGN((u32Width * u8BitWidth + 7) >> 3, u32Align); + u32CSize = u32CStride * u32AlignHeight; + + u32MainSize = u32YSize + u32CSize; + pstCalConfig->plane_num = 2; + } else if (enPixelFormat == PIXEL_FORMAT_YUYV || enPixelFormat == PIXEL_FORMAT_YVYU || + enPixelFormat == PIXEL_FORMAT_UYVY || enPixelFormat == PIXEL_FORMAT_VYUY) { + u32MainStride = ALIGN(((u32Width * u8BitWidth + 7) >> 3) * 2, u32Align); + u32YSize = u32MainStride * u32AlignHeight; + u32MainSize = u32YSize; + pstCalConfig->plane_num = 1; + } else if (enPixelFormat == PIXEL_FORMAT_ARGB_1555 || enPixelFormat == PIXEL_FORMAT_ARGB_4444) { + // packed format + u32MainStride = ALIGN((u32Width * 16 + 7) >> 3, u32Align); + u32YSize = u32MainStride * u32AlignHeight; + u32MainSize = u32YSize; + pstCalConfig->plane_num = 1; + } else if (enPixelFormat == PIXEL_FORMAT_ARGB_8888) { + // packed format + u32MainStride = ALIGN((u32Width * 32 + 7) >> 3, u32Align); + u32YSize = u32MainStride * u32AlignHeight; + u32MainSize = u32YSize; + pstCalConfig->plane_num = 1; + } else { + // packed format + u32MainStride = ALIGN(((u32Width * u8BitWidth + 7) >> 3) * 3, u32Align); + u32YSize = u32MainStride * u32AlignHeight; + u32MainSize = u32YSize; + pstCalConfig->plane_num = 1; + } + + u32VBSize = u32MainSize; + } else { + // TODO: compression mode + pstCalConfig->plane_num = 0; + } + + pstCalConfig->u32VBSize = u32VBSize; + pstCalConfig->u32MainStride = u32MainStride; + pstCalConfig->u32CStride = u32CStride; + pstCalConfig->u32MainYSize = u32YSize; + pstCalConfig->u32MainCSize = u32CSize; + pstCalConfig->u32MainSize = u32MainSize; + pstCalConfig->u16AddrAlign = u32Align; +} + +static inline CVI_U32 COMMON_GetPicBufferSize(CVI_U32 u32Width, CVI_U32 u32Height, PIXEL_FORMAT_E enPixelFormat, + DATA_BITWIDTH_E enBitWidth, COMPRESS_MODE_E enCmpMode, CVI_U32 u32Align) +{ + VB_CAL_CONFIG_S stCalConfig; + + COMMON_GetPicBufferConfig(u32Width, u32Height, enPixelFormat, enBitWidth, enCmpMode, u32Align, &stCalConfig); + + return stCalConfig.u32VBSize; +} + + +#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S)) + +static inline CVI_U32 COMMON_GetVencFrameBufferSize(CVI_S32 s32Codec, CVI_U32 u32Width, CVI_U32 u32Height) +{ + CVI_U32 u32RetSize = 0; + + if (s32Codec == PT_H264) { + CVI_U32 u32WidthAlign = (ALIGN(u32Width, DEFAULT_ALIGN)); + CVI_U32 u32HeightAlign = (ALIGN(u32Width, DEFAULT_ALIGN)); + + u32RetSize = (u32WidthAlign * u32HeightAlign * 2 * 3) / 2; + } else if (s32Codec == PT_H265) { + u32RetSize = ((u32Width * u32Height * 3) / 2); + u32RetSize = ROUND_UP(u32RetSize, 4096) * 2; + } else + u32RetSize = 0; + + return u32RetSize; +} +static inline CVI_U32 VI_GetRawBufferSize(CVI_U32 u32Width, CVI_U32 u32Height, PIXEL_FORMAT_E enPixelFormat, + COMPRESS_MODE_E enCmpMode, CVI_U32 u32Align, CVI_BOOL isTile) +{ + CVI_U32 u32BitWidth; + CVI_U32 u32Size = 0; + CVI_U32 u32Stride = 0; + + /* u32Align: 0 is automatic mode, alignment size following system. Non-0 for specified alignment size */ + if (u32Align == 0) + u32Align = DEFAULT_ALIGN; + else if (u32Align > MAX_ALIGN) + u32Align = MAX_ALIGN; + else + u32Align = (ALIGN(u32Align, DEFAULT_ALIGN)); + + switch (enPixelFormat) { + case PIXEL_FORMAT_RGB_BAYER_8BPP: { + u32BitWidth = 8; + break; + } + + case PIXEL_FORMAT_RGB_BAYER_10BPP: { + u32BitWidth = 10; + break; + } + + case PIXEL_FORMAT_RGB_BAYER_12BPP: { + u32BitWidth = 12; + break; + } + + case PIXEL_FORMAT_RGB_BAYER_14BPP: { + u32BitWidth = 14; + break; + } + + case PIXEL_FORMAT_RGB_BAYER_16BPP: { + u32BitWidth = 16; + break; + } + + default: { + u32BitWidth = 0; + break; + } + } + + if (enCmpMode == COMPRESS_MODE_NONE) { + u32Stride = ALIGN(ALIGN(u32Width * u32BitWidth, 8) / 8, u32Align); + u32Size = u32Stride * u32Height; + } else if (enCmpMode == COMPRESS_MODE_TILE || enCmpMode == COMPRESS_MODE_FRAME) { + u32Width = (isTile) ? ((u32Width + 8) >> 1) : (u32Width >> 1); + u32Width = 3 * ((u32Width + 1) >> 1); + + u32Stride = ALIGN(u32Width, 16); + u32Size = u32Stride * u32Height; + } + + return u32Size; +} + +static inline CVI_VOID VDEC_GetPicBufferConfig(PAYLOAD_TYPE_E enType, + CVI_U32 u32Width, CVI_U32 u32Height, + PIXEL_FORMAT_E enPixelFormat, DATA_BITWIDTH_E enBitWidth, + COMPRESS_MODE_E enCmpMode, VB_CAL_CONFIG_S *pstVbCfg) +{ + CVI_U32 u32AlignWidth = 0, u32AlignHeight = 0, u32Align = 0; + + if (enType == PT_H264) { + u32AlignWidth = ALIGN(u32Width, H264D_ALIGN_W); + u32AlignHeight = ALIGN(u32Height, H264D_ALIGN_H); + u32Align = H264D_ALIGN_W; + } else if (enType == PT_H265) { + u32AlignWidth = ALIGN(u32Width, H265D_ALIGN_W); + u32AlignHeight = ALIGN(u32Height, H265D_ALIGN_H); + u32Align = H265D_ALIGN_W; + } else if ((enType == PT_JPEG) || (enType == PT_MJPEG)) { + u32AlignWidth = ALIGN(u32Width, JPEGD_ALIGN_W); + u32AlignHeight = ALIGN(u32Height, JPEGD_ALIGN_H); + u32Align = JPEGD_ALIGN_W; + } else { + u32AlignWidth = ALIGN(u32Width, DEFAULT_ALIGN); + u32AlignHeight = ALIGN(u32Height, DEFAULT_ALIGN); + u32Align = DEFAULT_ALIGN; + } + + COMMON_GetPicBufferConfig(u32AlignWidth, u32AlignHeight, enPixelFormat, + enBitWidth, enCmpMode, u32Align, pstVbCfg); +} + +static inline CVI_U32 VDEC_GetPicBufferSize(PAYLOAD_TYPE_E enType, + CVI_U32 u32Width, CVI_U32 u32Height, + PIXEL_FORMAT_E enPixelFormat, DATA_BITWIDTH_E enBitWidth, + COMPRESS_MODE_E enCmpMode) +{ + VB_CAL_CONFIG_S stVbCfg; + + memset(&stVbCfg, 0, sizeof(stVbCfg)); + VDEC_GetPicBufferConfig(enType, u32Width, u32Height, enPixelFormat, enBitWidth, enCmpMode, &stVbCfg); + return stVbCfg.u32VBSize; +} + +static inline CVI_VOID VENC_GetPicBufferConfig(CVI_U32 u32Width, CVI_U32 u32Height, + PIXEL_FORMAT_E enPixelFormat, DATA_BITWIDTH_E enBitWidth, COMPRESS_MODE_E enCmpMode, + VB_CAL_CONFIG_S *pstVbCfg) +{ + CVI_U32 u32AlignWidth = ALIGN(u32Width, VENC_ALIGN_W); + CVI_U32 u32AlignHeight = ALIGN(u32Height, VENC_ALIGN_H); + CVI_U32 u32Align = VENC_ALIGN_W; + + COMMON_GetPicBufferConfig(u32AlignWidth, u32AlignHeight, enPixelFormat, + enBitWidth, enCmpMode, u32Align, pstVbCfg); +} + +static inline CVI_U32 VENC_GetPicBufferSize(CVI_U32 u32Width, CVI_U32 u32Height, + PIXEL_FORMAT_E enPixelFormat, DATA_BITWIDTH_E enBitWidth, COMPRESS_MODE_E enCmpMode) +{ + VB_CAL_CONFIG_S stVbCfg; + + memset(&stVbCfg, 0, sizeof(stVbCfg)); + VENC_GetPicBufferConfig(u32Width, u32Height, enPixelFormat, enBitWidth, enCmpMode, &stVbCfg); + return stVbCfg.u32VBSize; +} + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* __CVI_BUFFER_H__ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_comm_adec.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_comm_adec.h new file mode 100644 index 00000000..5fd264a4 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_comm_adec.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. + * + * File Name: include/cvi_comm_adec.h + * Description: basic audio decoder api for application layer + */ + +#ifndef __CVI_COMM_ADEC_H__ +#define __CVI_COMM_ADEC_H__ + + +#include +#include +#include "cvi_comm_aio.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* End of #ifdef __cplusplus */ + +typedef struct _ADEC_ATTR_G711_S { + CVI_U32 resv; +} ADEC_ATTR_G711_S; + +typedef struct _ADEC_ATTR_G726_S { + G726_BPS_E enG726bps; +} ADEC_ATTR_G726_S; + +typedef struct _ADEC_ATTR_ADPCM_S { + ADPCM_TYPE_E enADPCMType; +} ADEC_ATTR_ADPCM_S; + +typedef struct _ADEC_ATTR_LPCM_S { + CVI_U32 resv; +} ADEC_ATTR_LPCM_S; + +typedef enum _ADEC_MODE_E { + ADEC_MODE_PACK = 0, + /*require input is valid dec pack(a */ + /*complete frame encode result),*/ + /*e.g.the stream get from AENC is a*/ + /*valid dec pack, the stream know actually*/ + /*pack len from file is also a dec pack.*/ + /*this mode is high-performative*/ + ADEC_MODE_STREAM, + /*input is stream,low-performative, */ + /*if you couldn't find out whether a stream is*/ + /*valid dec pack,you could use*/ + /*this mode*/ + ADEC_MODE_BUTT +} ADEC_MODE_E; + +typedef struct _ADEC_CH_ATTR_S { + PAYLOAD_TYPE_E enType; + CVI_U32 u32BufSize; /*buf size[2~CVI_MAX_AUDIO_FRAME_NUM]*/ + ADEC_MODE_E enMode;/*decode mode*/ + /* CVI_VOID ATTRIBUTE *pValue;*/ + CVI_VOID *pValue; + CVI_BOOL bFileDbgMode; + //------user should update these information if + //ao not enable + CVI_S32 s32BytesPerSample; + CVI_S32 s32frame_size; //in samples + CVI_S32 s32ChannelNums; // 1 or 2 + CVI_S32 s32Sample_rate; +} ADEC_CHN_ATTR_S; + +typedef struct _ADEC_CHN_STATE_S { + CVI_BOOL bEndOfStream; /* EOS flag */ + CVI_U32 u32BufferFrmNum; /* total number of channel buffer */ + CVI_U32 u32BufferFreeNum; /* free number of channel buffer */ + CVI_U32 u32BufferBusyNum; /* busy number of channel buffer */ +} ADEC_CHN_STATE_S; + +typedef struct _ADEC_DECODER_S { + PAYLOAD_TYPE_E enType; + CVI_CHAR aszName[17]; + + CVI_S32 (*pfnOpenDecoder)(CVI_VOID *pDecoderAttr, CVI_VOID **ppDecoder); + CVI_S32 (*pfnDecodeFrm)(CVI_VOID *pDecoder, CVI_U8 **pu8Inbuf, + CVI_S32 *ps32LeftByte, + CVI_U16 *pu16Outbuf, CVI_U32 *pu32OutLen, CVI_U32 *pu32Chns); + CVI_S32 (*pfnGetFrmInfo)(CVI_VOID *pDecoder, CVI_VOID *pInfo); + CVI_S32 (*pfnCloseDecoder)(CVI_VOID *pDecoder); + CVI_S32 (*pfnResetDecoder)(CVI_VOID *pDecoder); +} ADEC_DECODER_S; + +/* invalid device ID */ +#define CVI_ERR_ADEC_INVALID_DEVID 0xA3000001 +/* invalid channel ID */ +#define CVI_ERR_ADEC_INVALID_CHNID 0xA3000002 +/* at least one parameter is illegal ,eg, an illegal enumeration value */ +#define CVI_ERR_ADEC_ILLEGAL_PARAM 0xA3000003 +/* channel exists */ +#define CVI_ERR_ADEC_EXIST 0xA3000004 +/* channel unexists */ +#define CVI_ERR_ADEC_UNEXIST 0xA3000005 +/* using a NULL point */ +#define CVI_ERR_ADEC_NULL_PTR 0xA3000006 +/* try to enable or initialize system,device or channel, before configing attribute */ +#define CVI_ERR_ADEC_NOT_CONFIG 0xA3000007 +/* operation is not supported by NOW */ +#define CVI_ERR_ADEC_NOT_SUPPORT 0xA3000008 +/* operation is not permitted ,eg, try to change stati attribute */ +#define CVI_ERR_ADEC_NOT_PERM 0xA3000009 +/* failure caused by malloc memory */ +#define CVI_ERR_ADEC_NOMEM 0xA300000A +/* failure caused by malloc buffer */ +#define CVI_ERR_ADEC_NOBUF 0xA300000B +/* no data in buffer */ +#define CVI_ERR_ADEC_BUF_EMPTY 0xA300000C +/* no buffer for new data */ +#define CVI_ERR_ADEC_BUF_FULL 0xA300000D +/* system is not ready,had not initialized or loaded*/ +#define CVI_ERR_ADEC_SYS_NOTREADY 0xA300000E +/* decoder internal err */ +#define CVI_ERR_ADEC_DECODER_ERR 0xA300000F +/* input buffer not enough to decode one frame */ +#define CVI_ERR_ADEC_BUF_LACK 0xA3000010 + + + + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + +#endif/* End of #ifndef __CVI_COMM_ADEC_H__*/ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_comm_aenc.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_comm_aenc.h new file mode 100644 index 00000000..b978bf01 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_comm_aenc.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. + * + * File Name: include/cvi_comm_aenc.h + * Description: basic audio audio + * encoder api for application layer + */ +#ifndef __CVI_COMM_AENC_H__ +#define __CVI_COMM_AENC_H__ + +#include +#include +#include "cvi_comm_aio.h" + + + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* End of #ifdef __cplusplus */ + +typedef struct _AENC_ATTR_G711_S { + CVI_U32 resv; /*reserve item*/ +} AENC_ATTR_G711_S; + +typedef struct _AENC_ATTR_G726_S { + G726_BPS_E enG726bps; +} AENC_ATTR_G726_S; + +typedef struct _AENC_ATTR_ADPCM_S { + ADPCM_TYPE_E enADPCMType; +} AENC_ATTR_ADPCM_S; + +typedef struct _AENC_ATTR_LPCM_S { + CVI_U32 resv; /*reserve item*/ +} AENC_ATTR_LPCM_S; + +typedef struct _AAC_AENC_ENCODER_S { + PAYLOAD_TYPE_E enType; + CVI_U32 u32MaxFrmLen; + CVI_CHAR aszName[17]; + /* encoder type,be used to print proc information */ + CVI_S32 (*pfnOpenEncoder)(CVI_VOID *pEncoderAttr, CVI_VOID **ppEncoder); + /* pEncoder is the handle to control the encoder */ +#if 0 + CVI_S32 (*pfnEncodeFrm)(CVI_VOID *pEncoder, const AUDIO_FRAME_S *pstData, + CVI_U8 *pu8Outbuf, CVI_U32 *pu32OutLen); +#endif +CVI_S32 (*pfnEncodeFrm)(CVI_VOID *pEncoder, CVI_S16 * inputdata, CVI_U8 * pu8Outbuf, + CVI_S32 s32InputSizeBytes, CVI_U32 *pu32OutLen); + CVI_S32 (*pfnCloseEncoder)(CVI_VOID *pEncoder); +} AAC_AENC_ENCODER_S; + +typedef struct _AENC_CHN_ATTR_S { + PAYLOAD_TYPE_E enType; /*payload type ()*/ + CVI_U32 u32PtNumPerFrm; + CVI_U32 u32BufSize; /*buf size [2~CVI_MAX_AUDIO_FRAME_NUM]*/ + /* CVI_VOID ATTRIBUTE *pValue; point to attribute of definite audio encoder*/ + CVI_VOID *pValue; + CVI_BOOL bFileDbgMode; +} AENC_CHN_ATTR_S; + +typedef enum _EN_AENC_ERR_CODE_E { + AENC_ERR_ENCODER_ERR = 64, + AENC_ERR_VQE_ERR = 65, + +} EN_AENC_ERR_CODE_E; + + +/* invalid device ID */ +#define CVI_ERR_AENC_INVALID_DEVID 0xA2000001 +/* invalid channel ID */ +#define CVI_ERR_AENC_INVALID_CHNID 0xA2000002 +/* at least one parameter is illegal ,eg, an illegal enumeration value */ +#define CVI_ERR_AENC_ILLEGAL_PARAM 0xA2000003 +/* channel exists */ +#define CVI_ERR_AENC_EXIST 0xA2000004 +/* channel unexists */ +#define CVI_ERR_AENC_UNEXIST 0xA2000005 +/* using a NULL point */ +#define CVI_ERR_AENC_NULL_PTR 0xA2000006 +/* try to enable or initialize system,device or channel, before configing attribute */ +#define CVI_ERR_AENC_NOT_CONFIG 0xA2000007 +/* operation is not supported by NOW */ +#define CVI_ERR_AENC_NOT_SUPPORT 0xA2000008 +/* operation is not permitted ,eg, try to change static attribute */ +#define CVI_ERR_AENC_NOT_PERM 0xA2000009 +/* failure caused by malloc memory */ +#define CVI_ERR_AENC_NOMEM 0xA200000A +/* failure caused by malloc buffer */ +#define CVI_ERR_AENC_NOBUF 0xA200000B +/* no data in buffer */ +#define CVI_ERR_AENC_BUF_EMPTY 0xA200000C +/* no buffer for new data */ +#define CVI_ERR_AENC_BUF_FULL 0xA200000D +/* system is not ready,had not initialized or loaded*/ +#define CVI_ERR_AENC_SYS_NOTREADY 0xA200000E +/* encoder internal err */ +#define CVI_ERR_AENC_ENCODER_ERR 0xA200000F +/* vqe internal err */ +#define CVI_ERR_AENC_VQE_ERR 0xA2000010 + + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + +#endif/* End of #ifndef __CVI_COMM_AENC_H__*/ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_comm_aio.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_comm_aio.h new file mode 100644 index 00000000..1ecd79ff --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_comm_aio.h @@ -0,0 +1,580 @@ +/* + * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. + * + * File Name: include/cvi_comm_aio.h + * Description: basic audio in out definition + */ + +#ifndef __CVI_COMM_AIO_H__ +#define __CVI_COMM_AIO_H__ + +#include +#include + + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* End of #ifdef __cplusplus */ + + +#define CVI_MAX_AUDIO_FRAME_NUM 300 /*max count of audio frame in Buffer */ +#define CVI_AUD_MAX_VOICE_POINT_NUM 1280 /*max sample per frame for voice encode */ +#define CVI_AUD_MAX_AUDIO_POINT_NUM 2048 /*max sample per frame for all encoder(aacplus:2048)*/ +#define CVI_AUD_MAX_CHANNEL_NUM 3 +#define CVI_MAX_AUDIO_STREAM_LEN (4 * 4096) + + + +#define MAX_AUDIO_FILE_PATH_LEN 256 +#define MAX_AUDIO_FILE_NAME_LEN 256 +#define MAX_AUDIO_VQE_CUSTOMIZE_NAME 64 + +/*The VQE EQ Band num.*/ +#define VQE_EQ_BAND_NUM 10 + +#define AI_RECORDVQE_MASK_HPF 0x1 +#define AI_RECORDVQE_MASK_RNR 0x2 +#define AI_RECORDVQE_MASK_HDR 0x4 +#define AI_RECORDVQE_MASK_DRC 0x8 +#define AI_RECORDVQE_MASK_EQ 0x10 +#define AI_RECORDVQE_MASK_AGC 0x20 + + +//#define AI_TALKVQE_MASK_HPF 0x1//not support +#define AI_TALKVQE_MASK_AEC 0x3 +#define AI_TALKVQE_MASK_ANR 0x4 +#define AI_TALKVQE_MASK_AGC 0x8 +#define AI_TALKVQE_MASK_NOTCH_FILTER 0x30 +//#define AI_TALKVQE_MASK_EQ 0x10//not supoort +#define NEXT_SSP_ALGO 1 + + +/* LP AEC Control */ +#define LP_AEC_ENABLE 0x1 /* bit 0 */ +/* NLP AES Control */ +#define NLP_AES_ENABLE 0x2 /* bit 1 */ +/* NR Control */ +#define NR_ENABLE 0x4 /* bit 2 */ +/* AGC Control */ +#define AGC_ENABLE 0x8 /* bit 3 */ +/* Notch Filter Control */ +#define NOTCH_ENABLE 0x10 /* bit 4 */ +/* DC Filter Control */ +#define DCREMOVER_ENABLE 0x20 /* bit 5 */ +/* DG Control */ +#define DG_ENABLE 0x40 /* bit 6 */ +/* Delay Control */ +#define DELAY_ENABLE 0x80 /* bit 7 */ + +//control for AO_VQE +/* AGC Control in SPK Path */ +#define SPK_AGC_ENABLE 0x1 /* bit 0 */ +#define SPK_EQ_ENABLE 0x2 /* bit 1 */ + +#define CVI_MAX_AI_DEVICE_ID_NUM 3 +#define CVI_MAX_AO_DEVICE_ID_NUM 3 +/* define macro */ + +#define CHECK_AI_DEVID_VALID(x) \ + ((((x) > (CVI_MAX_AI_DEVICE_ID_NUM-1))) ? 1:0) +#define CHECK_AO_DEVID_VALID(x) \ + ((((x) > (CVI_MAX_AO_DEVICE_ID_NUM-1))) ? 1:0) +#define CHECK_AENC_DEVID_VALID(x) \ + ((((x) > (AENC_MAX_CHN_NUM-1))) ? 1:0) +#define CHECK_ADEC_DEVID_VALID(x) \ + ((((x) > (ADEC_MAX_CHN_NUM-1))) ? 1:0) + + +typedef enum _AUDIO_SAMPLE_RATE_E { + AUDIO_SAMPLE_RATE_8000 = 8000, /* 8K samplerate*/ + /* 12K samplerate(not support in this version)*/ + AUDIO_SAMPLE_RATE_11025 = 11025, /* 11.025K samplerate*/ + AUDIO_SAMPLE_RATE_16000 = 16000, /* 16K samplerate*/ + AUDIO_SAMPLE_RATE_22050 = 22050, /* 22.050K samplerate*/ + AUDIO_SAMPLE_RATE_24000 = 24000, /* 24K samplerate*/ + AUDIO_SAMPLE_RATE_32000 = 32000, /* 32K samplerate*/ + AUDIO_SAMPLE_RATE_44100 = 44100, /* 44.1K samplerate*/ + AUDIO_SAMPLE_RATE_48000 = 48000, /* 48K samplerate*/ + AUDIO_SAMPLE_RATE_64000 = 64000, /* 64K samplerate*/ + /* 96K samplerate is not support in cv183x series*/ + AUDIO_SAMPLE_RATE_BUTT, +} AUDIO_SAMPLE_RATE_E; + +typedef enum _AUDIO_BIT_WIDTH_E { + AUDIO_BIT_WIDTH_8 = 0, /* 8bit width */ + AUDIO_BIT_WIDTH_16 = 1, /* 16bit width*/ + AUDIO_BIT_WIDTH_24 = 2, /* 24bit width*/ + AUDIO_BIT_WIDTH_32 = 3, /* 24bit width*/ + AUDIO_BIT_WIDTH_BUTT, +} AUDIO_BIT_WIDTH_E; + +typedef enum _AIO_MODE_E { + AIO_MODE_I2S_MASTER = 0, /* AIO I2S master mode */ + AIO_MODE_I2S_SLAVE, /* AIO I2S slave mode */ + AIO_MODE_PCM_SLAVE_STD, /* AIO PCM slave standard mode */ + AIO_MODE_PCM_SLAVE_NSTD, /* AIO PCM slave non-standard mode */ + AIO_MODE_PCM_MASTER_STD, /* AIO PCM master standard mode */ + AIO_MODE_PCM_MASTER_NSTD, /* AIO PCM master non-standard mode */ + AIO_MODE_BUTT +} AIO_MODE_E; + +typedef enum { + AIO_I2STYPE_INNERCODEC = 0, /* AIO I2S connect inner audio CODEC */ + AIO_I2STYPE_INNERHDMI, /* AIO I2S connect Inner HDMI */ + AIO_I2STYPE_EXTERN, /* AIO I2S connect extern hardware */ +} AIO_I2STYPE_E; + +typedef enum _AIO_SOUND_MODE_E { + AUDIO_SOUND_MODE_MONO = 0, /*mono*/ + AUDIO_SOUND_MODE_STEREO = 1, /*stereo only support interlace mode*/ + AUDIO_SOUND_MODE_BUTT +} AUDIO_SOUND_MODE_E; + +/*An example of the packing scheme for G726-32 codewords is as */ +/*shown, and bit A3 is the least significant */ +/*bit of the first codeword:*/ +/*RTP G726-32:*/ +/*0 1*/ +/*0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5*/ +/*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-*/ +/*|B B B B|A A A A|D D D D|C C C C| ...*/ +/*|0 1 2 3|0 1 2 3|0 1 2 3|0 1 2 3|*/ +/*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-*/ +/*MEDIA G726-32:*/ +/*0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5*/ +/*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-*/ +/*|A A A A|B B B B|C C C C|D D D D| ...*/ +/*|3 2 1 0|3 2 1 0|3 2 1 0|3 2 1 0|*/ +/*+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-*/ +typedef enum _G726_BPS_E { + G726_16K = 0, /* G726 16kbps, see RFC3551.txt 4.5.4 G726-16 */ + G726_24K, /* G726 24kbps, see RFC3551.txt 4.5.4 G726-24 */ + G726_32K, /* G726 32kbps, see RFC3551.txt 4.5.4 G726-32 */ + G726_40K, /* G726 40kbps, see RFC3551.txt 4.5.4 G726-40 */ + MEDIA_G726_16K, /* G726 16kbps for ASF ... */ + MEDIA_G726_24K, /* G726 24kbps for ASF ... */ + MEDIA_G726_32K, /* G726 32kbps for ASF ... */ + MEDIA_G726_40K, /* G726 40kbps for ASF ... */ + G726_BUTT, +} G726_BPS_E; + +typedef enum _ADPCM_TYPE_E { + /* see DVI4 diiffers in three respects from the IMA ADPCM at RFC3551.txt 4.5.1 DVI4 */ + + ADPCM_TYPE_DVI4 = 0, /* 32kbps ADPCM(DVI4) for RTP */ + ADPCM_TYPE_IMA, /* 32kbps ADPCM(IMA),NOTICE:point num must be 161/241/321/481 */ + ADPCM_TYPE_ORG_DVI4, + ADPCM_TYPE_BUTT, +} ADPCM_TYPE_E; + +#define AI_EXPAND 0x01 +#define AI_CUT 0x02 + +typedef struct _AIO_ATTR_S { + AUDIO_SAMPLE_RATE_E enSamplerate; /* sample rate */ + AUDIO_BIT_WIDTH_E enBitwidth; /* bitwidth */ + AIO_MODE_E enWorkmode; /* master or slave mode */ + AUDIO_SOUND_MODE_E enSoundmode; /* momo or steror */ + CVI_U32 u32EXFlag; + /* expand 8bit to 16bit,use AI_EXPAND(only valid for AI 8bit),*/ + /*use AI_CUT(only valid for extern Codec for 24bit) */ + CVI_U32 u32FrmNum; + /* frame num in buf[2,CVI_MAX_AUDIO_FRAME_NUM] */ + CVI_U32 u32PtNumPerFrm; + /* point num per frame (80/160/240/320/480/1024/2048) */ + /*(ADPCM IMA should add 1 point, AMR only support 160) */ + CVI_U32 u32ChnCnt; /* channel number on FS, valid value:1/2/4/8 */ + CVI_U32 u32ClkSel; /* 0: AI and AO clock is separate*/ + /* 1: AI and AO clock is inseparate, AI use AO's clock*/ + AIO_I2STYPE_E enI2sType; /* i2s type */ +} AIO_ATTR_S; + +typedef struct _AI_CHN_PARAM_S { + CVI_U32 u32UsrFrmDepth; +} AI_CHN_PARAM_S; + +typedef struct _AUDIO_FRAME_S { + AUDIO_BIT_WIDTH_E enBitwidth;/*audio frame bitwidth*/ + AUDIO_SOUND_MODE_E enSoundmode;/*audio frame momo or stereo mode*/ + CVI_U8 * u64VirAddr[2]; + CVI_U64 u64PhyAddr[2]; + CVI_U64 u64TimeStamp; /*audio frame timestamp*/ + CVI_U32 u32Seq; /*audio frame seq*/ + CVI_U32 u32Len; /*data length per channel in frame*/ + CVI_U32 u32PoolId[2]; +} AUDIO_FRAME_S; + +typedef struct _AEC_FRAME_S { + AUDIO_FRAME_S stRefFrame; /* AEC reference audio frame */ + CVI_BOOL bValid; /* whether frame is valid */ + CVI_BOOL bSysBind; /* whether is sysbind */ +} AEC_FRAME_S; + + +typedef struct _AUDIO_FRAME_INFO_S { + AUDIO_FRAME_S *pstFrame;/*frame ptr*/ + CVI_U32 u32Id; /*frame id*/ +} AUDIO_FRAME_INFO_S; + +typedef struct _AUDIO_STREAM_S { + /* CVI_U8 ATTRIBUTE *pStream;the virtual address of stream */ + /* CVI_U64 ATTRIBUTE u64PhyAddr; the physics address of stream */ + CVI_U8 *pStream; /* the virtual address of stream */ + CVI_U64 u64PhyAddr; /* the physics address of stream */ + CVI_U32 u32Len; /* stream length, by bytes */ + CVI_U64 u64TimeStamp; /* frame time stamp*/ + CVI_U32 u32Seq; /* frame seq,if stream is not a valid frame,u32Seq is 0*/ +} AUDIO_STREAM_S; + + +typedef struct _AO_CHN_STATE_S { + CVI_U32 u32ChnTotalNum; /* total number of channel buffer */ + CVI_U32 u32ChnFreeNum; /* free number of channel buffer */ + CVI_U32 u32ChnBusyNum; /* busy number of channel buffer */ +} AO_CHN_STATE_S; + +typedef enum _AUDIO_TRACK_MODE_E { + AUDIO_TRACK_NORMAL = 0, + AUDIO_TRACK_BOTH_LEFT = 1, + AUDIO_TRACK_BOTH_RIGHT = 2, + AUDIO_TRACK_EXCHANGE = 3, + AUDIO_TRACK_MIX = 4, + AUDIO_TRACK_LEFT_MUTE = 5, + AUDIO_TRACK_RIGHT_MUTE = 6, + AUDIO_TRACK_BOTH_MUTE = 7, + + AUDIO_TRACK_BUTT +} AUDIO_TRACK_MODE_E; + + +typedef enum _AUDIO_FADE_RATE_E { + AUDIO_FADE_RATE_NONE = 0, + AUDIO_FADE_RATE_10 = 10, + AUDIO_FADE_RATE_20 = 20, + AUDIO_FADE_RATE_30 = 30, + AUDIO_FADE_RATE_50 = 50, + AUDIO_FADE_RATE_100 = 100, + AUDIO_FADE_RATE_200 = 200, + AUDIO_FADE_RATE_BUTT = -1 +} AUDIO_FADE_RATE_E; + +typedef struct _AUDIO_FADE_S { + CVI_BOOL bFade; + AUDIO_FADE_RATE_E enFadeInRate; + AUDIO_FADE_RATE_E enFadeOutRate; +} AUDIO_FADE_S; + +/**Defines the configure parameters of AEC.*/ +typedef struct _AI_AEC_CONFIG_S { + CVI_U16 para_aec_filter_len; + CVI_U16 para_aes_std_thrd; /* the threshold of STD/DTD, [0, 35] */ + CVI_U16 para_aes_supp_coeff; /* the residual echo suppression level in AES, [0, 24] */ +} AI_AEC_CONFIG_S; + +/**Defines the configure parameters of UPVQE work state.*/ +typedef enum _VQE_WORKSTATE_E { + VQE_WORKSTATE_COMMON = 0, + /* common environment, Applicable to the family of voice calls. */ + VQE_WORKSTATE_MUSIC = 1, + /* music environment , Applicable to the family of music environment. */ + VQE_WORKSTATE_NOISY = 2, + /* noisy environment , Applicable to the noisy voice calls. */ +} VQE_WORKSTATE_E; + +/**Defines record type*/ +typedef enum _VQE_RECORD_TYPE { + VQE_RECORD_NORMAL = 0, + /* +#include +#include "cvi_debug.h" +#include "cvi_comm_isp.h" + +// ++++++++ If you want to change these interfaces, please contact the isp team. ++++++++ + +#define NOISE_PROFILE_CHANNEL_NUM 4 +#define NOISE_PROFILE_LEVEL_NUM 2 +#define NOISE_PROFILE_ISO_NUM 16 +#define USE_USER_SEN_DRIVER 1 + + +typedef struct _ISP_CMOS_SENSOR_IMAGE_MODE_S { + CVI_U16 u16Width; + CVI_U16 u16Height; + CVI_FLOAT f32Fps; + CVI_U8 u8SnsMode; +} ISP_CMOS_SENSOR_IMAGE_MODE_S; + +typedef struct _ISP_CMOS_BLACK_LEVEL_S { + CVI_BOOL bUpdate; + ISP_BLACK_LEVEL_ATTR_S blcAttr; +} ISP_CMOS_BLACK_LEVEL_S; + +typedef struct _ISP_SNS_ATTR_INFO_S { + CVI_U32 eSensorId; +} ISP_SNS_ATTR_INFO_S; + +typedef struct cviISP_CMOS_NOISE_CALIBRATION_S { + CVI_FLOAT CalibrationCoef[NOISE_PROFILE_ISO_NUM][NOISE_PROFILE_CHANNEL_NUM][NOISE_PROFILE_LEVEL_NUM]; +} ISP_CMOS_NOISE_CALIBRATION_S; + +typedef struct _ISP_CMOS_DEFAULT_S { + ISP_CMOS_NOISE_CALIBRATION_S stNoiseCalibration; +} ISP_CMOS_DEFAULT_S; + +typedef struct _ISP_SENSOR_EXP_FUNC_S { + CVI_VOID (*pfn_cmos_sensor_init)(VI_PIPE ViPipe); + CVI_VOID (*pfn_cmos_sensor_exit)(VI_PIPE ViPipe); + CVI_VOID (*pfn_cmos_sensor_global_init)(VI_PIPE ViPipe); + CVI_S32 (*pfn_cmos_set_image_mode)(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode); + CVI_S32 (*pfn_cmos_set_wdr_mode)(VI_PIPE ViPipe, CVI_U8 u8Mode); + + /* the algs get data which is associated with sensor, except 3a */ + CVI_S32 (*pfn_cmos_get_isp_default)(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef); + CVI_S32 (*pfn_cmos_get_isp_black_level)(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlackLevel); + CVI_S32 (*pfn_cmos_get_sns_reg_info)(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsRegsInfo); + + /* the function of sensor set pixel detect */ + //CVI_VOID (*pfn_cmos_set_pixel_detect)(VI_PIPE ViPipe, bool bEnable); +} ISP_SENSOR_EXP_FUNC_S; + +typedef struct bmISP_SENSOR_REGISTER_S { + ISP_SENSOR_EXP_FUNC_S stSnsExp; +} ISP_SENSOR_REGISTER_S; + +typedef enum _MCLK_FREQ_E { + MCLK_FREQ_NONE = 0, + MCLK_FREQ_37P125M, + MCLK_FREQ_25M, + MCLK_FREQ_27M, + MCLK_FREQ_NUM +} MCLK_FREQ_E; + +typedef struct _SNS_MCLK_S { + CVI_U32 u8Cam; + MCLK_FREQ_E enFreq; +} SNS_MCLK_S; + +// -------- If you want to change these interfaces, please contact the isp team. -------- + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif + +#endif /* _CVI_COMM_SNS_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_comm_vb.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_comm_vb.h new file mode 100644 index 00000000..09fed83e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_comm_vb.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. + * + * File Name: include/cvi_comm_vb.h + * Description: + * The common data type defination for VB module. + */ + +#ifndef __CVI_COMM_VB_H__ +#define __CVI_COMM_VB_H__ + +#include +#include +#include +#include "cvi_debug.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* End of #ifdef __cplusplus */ + +#define VB_INVALID_POOLID (-1U) +#define VB_INVALID_HANDLE (-1U) +#define VB_STATIC_POOLID (-2U) +#define VB_EXTERNAL_POOLID (-3U) + +#define VB_MAX_COMM_POOLS (16) +#define VB_POOL_MAX_BLK (64) + +/* user ID for VB */ +#define VB_MAX_USER VB_UID_BUTT + +typedef enum _VB_UID_E { + VB_UID_VI = 0, + VB_UID_VO = 1, + VB_UID_VPSS = 2, + VB_UID_VENC = 3, + VB_UID_VDEC = 4, + VB_UID_H265E = 5, + VB_UID_H264E = 6, + VB_UID_JPEGE = 7, + VB_UID_H264D = 8, + VB_UID_JPEGD = 9, + VB_UID_DIS = 10, + VB_UID_USER = 11, + VB_UID_AI = 12, + VB_UID_AENC = 13, + VB_UID_RC = 14, + VB_UID_VFMW = 15, + VB_UID_GDC = 16, + VB_UID_BUTT, + +} VB_UID_E; + +/* Generall common pool use this owner id, module common pool use VB_UID as owner id */ +#define POOL_OWNER_COMMON -1 + +/* Private pool use this owner id */ +#define POOL_OWNER_PRIVATE -2 + +typedef CVI_U32 VB_POOL; +#ifdef __arm__ +typedef CVI_U32 VB_BLK; +#else +typedef CVI_U64 VB_BLK; +#endif + +/* + * VB_REMAP_MODE_NONE: no remap. + * VB_REMAP_MODE_NOCACHE: no cache remap. + * VB_REMAP_MODE_CACHED: cache remap. flush cache is needed. + */ +typedef enum _VB_REMAP_MODE_E { + VB_REMAP_MODE_NONE = 0, + VB_REMAP_MODE_NOCACHE = 1, + VB_REMAP_MODE_CACHED = 2, + VB_REMAP_MODE_BUTT +} VB_REMAP_MODE_E; + +/* + * u32BlkSize: size of blk in the pool. + * u32BlkCnt: number of blk in the pool. + * enRemapMode: remap mode. + */ +#define MAX_VB_POOL_NAME_LEN (32) +typedef struct _VB_POOL_CONFIG_S { + CVI_U32 u32BlkSize; + CVI_U32 u32BlkCnt; + VB_REMAP_MODE_E enRemapMode; + CVI_CHAR acName[MAX_VB_POOL_NAME_LEN]; +} VB_POOL_CONFIG_S; + +/* + * au64PhyAddr: Y/U/V base addr. + */ +typedef struct _VB_USER_BLOCK_S { + CVI_U64 au64PhyAddr[3]; +} VB_USER_BLOCK_S; + +/* + * u32BlkCnt: number of blk in the pool. + * VB_USER_BLOCK_S: block addr. + */ +typedef struct _VB_POOL_CONFIG_EX_S { + CVI_U32 u32BlkCnt; + VB_USER_BLOCK_S astUserBlk[VB_POOL_MAX_BLK]; +} VB_POOL_CONFIG_EX_S; + +/* + * u32MaxPoolCnt: number of common pools used. + * astCommPool: pool cfg for the pools. + */ +typedef struct _VB_CONFIG_S { + CVI_U32 u32MaxPoolCnt; + VB_POOL_CONFIG_S astCommPool[VB_MAX_COMM_POOLS]; +} VB_CONFIG_S; + +#define VB_SUPPLEMENT_JPEG_MASK 0x1 +#define VB_SUPPLEMENT_ISPINFO_MASK 0x2 +#define VB_SUPPLEMENT_MOTION_DATA_MASK 0x4 +#define VB_SUPPLEMENT_DNG_MASK 0x8 + +typedef struct _VB_SUPPLEMENT_CONFIG_S { + CVI_U32 u32SupplementConfig; +} VB_SUPPLEMENT_CONFIG_S; + + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* __CVI_COMM_VB_H_ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_debug.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_debug.h new file mode 100644 index 00000000..ff9b476e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_debug.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. + * + * File Name: include/cvi_debug.h + * Description: + */ + +#ifndef __CVI_DEBUG_H__ +#define __CVI_DEBUG_H__ + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* End of #ifdef __cplusplus */ + +/* + * Debug Config + */ +#define CONFIG_CVI_GDB_NO 1 +#define CONFIG_CVI_GDB "n" +#define CONFIG_CVI_LOG_TRACE_SUPPORT 1 +#define CONFIG_CVI_LOG_TRACE_ALL 1 +#define CONFIG_CVI_LOG_TRACE_LEVEL 4 + + +#define CVI_DBG_EMERG 0 /* system is unusable */ +#define CVI_DBG_ALERT 1 /* action must be taken immediately */ +#define CVI_DBG_CRIT 2 /* critical conditions */ +#define CVI_DBG_ERR 3 /* error conditions */ +#define CVI_DBG_WARN 4 /* warning conditions */ +#define CVI_DBG_NOTICE 5 /* normal but significant condition */ +#define CVI_DBG_INFO 6 /* informational */ +#define CVI_DBG_DEBUG 7 /* debug-level messages */ + +typedef struct _LOG_LEVEL_CONF_S { + MOD_ID_E enModId; + CVI_S32 s32Level; + char cModName[16]; +} LOG_LEVEL_CONF_S; + +#define CVI_PRINT printf + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-variable" + +extern CVI_S32 * log_levels; +extern CVI_CHAR const *log_name[8]; + +#pragma GCC diagnostic pop + +#define _GENERATE_STRING(STRING) (#STRING), +static const char *const MOD_STRING[] = FOREACH_MOD(_GENERATE_STRING); +#define CVI_GET_MOD_NAME(id) (id < CVI_ID_BUTT)? MOD_STRING[id] : "UNDEF" + +/* #ifdef CVI_DEBUG */ +#ifdef CONFIG_CVI_LOG_TRACE_SUPPORT + + #define CVI_ASSERT(expr) \ + do { \ + if (!(expr)) { \ + printf("\nASSERT at:\n" \ + " >Function : %s\n" \ + " >Line No. : %d\n" \ + " >Condition: %s\n", \ + __func__, __LINE__, #expr); \ + _exit(-1); \ + } \ + } while (0) + +#ifndef FPGA_PORTING + + #define CVI_TRACE(level, enModId, fmt, ...) \ + do { \ + CVI_S32 LogLevel = (log_levels == NULL) ? CONFIG_CVI_LOG_TRACE_LEVEL : log_levels[enModId]; \ + if (level <= LogLevel) \ + syslog(LOG_LOCAL5|level, "[%s-%s] " fmt, CVI_GET_MOD_NAME(enModId), log_name[level], \ + ##__VA_ARGS__); \ + } while (0) +#else + #define CVI_TRACE(level, enModId, fmt, ...) \ + printf(fmt, ##__VA_ARGS__) +#endif +#else + #define CVI_ASSERT(expr) + #define CVI_TRACE(level, enModId, fmt...) +#endif + +#define CVI_TRACE_ID(level, id, fmt, ...) \ + CVI_TRACE(level, id, "%s:%d:%s(): " fmt, __FILENAME__, __LINE__, __func__, ##__VA_ARGS__) + +#define CVI_TRACE_LOG(level, fmt, ...) \ + CVI_TRACE(level, CVI_ID_LOG, "%s:%d:%s(): " fmt, __FILENAME__, __LINE__, __func__, ##__VA_ARGS__) + +#define CVI_TRACE_SYS(level, fmt, ...) \ + CVI_TRACE(level, CVI_ID_SYS, "%s:%d:%s(): " fmt, __FILENAME__, __LINE__, __func__, ##__VA_ARGS__) + +#define CVI_TRACE_VB(level, fmt, ...) \ + CVI_TRACE(level, CVI_ID_VB, "%s:%d:%s(): " fmt, __FILENAME__, __LINE__, __func__, ##__VA_ARGS__) + +#define CVI_TRACE_SNS(level, fmt, ...) \ + CVI_TRACE(level, CVI_ID_VI, "%s:%d:%s(): " fmt, __FILENAME__, __LINE__, __func__, ##__VA_ARGS__) + +#define CVI_TRACE_VI(level, fmt, ...) \ + CVI_TRACE(level, CVI_ID_VI, "%s:%d:%s(): " fmt, __FILENAME__, __LINE__, __func__, ##__VA_ARGS__) + +#define CVI_TRACE_VPSS(level, fmt, ...) \ + CVI_TRACE(level, CVI_ID_VPSS, "%s:%d:%s(): " fmt, __FILENAME__, __LINE__, __func__, ##__VA_ARGS__) + +#define CVI_TRACE_VO(level, fmt, ...) \ + CVI_TRACE(level, CVI_ID_VO, "%s:%d:%s(): " fmt, __FILENAME__, __LINE__, __func__, ##__VA_ARGS__) + +#define CVI_TRACE_GDC(level, fmt, ...) \ + CVI_TRACE(level, CVI_ID_GDC, "%s:%d:%s(): " fmt, __FILENAME__, __LINE__, __func__, ##__VA_ARGS__) + +#define CVI_TRACE_RGN(level, fmt, ...) \ + CVI_TRACE(level, CVI_ID_RGN, "%s:%d:%s(): " fmt, __FILENAME__, __LINE__, __func__, ##__VA_ARGS__) + +#define CVI_TRACE_MISC(level, fmt, ...) \ + CVI_TRACE(level, CVI_ID_SYS, "%s:%d:%s(): " fmt, __FILENAME__, __LINE__, __func__, ##__VA_ARGS__) + + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* __CVI_COMM_SYS_H__ */ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_gdc.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_gdc.h new file mode 100644 index 00000000..fc4fd1fb --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_gdc.h @@ -0,0 +1,166 @@ +/* + * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. + * + * File Name: include/cvi_gdc.h + * Description: + * gdc interfaces. + */ + +#ifndef __CVI_GDC_H__ +#define __CVI_GDC_H__ + +#include +#include +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +/** + * @brief Begin a gdc job,then add task into the job,gdc will finish all the task in the job. + * + * @param hHandle(In), handle creat by CVI_GDC_BeginJob + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_GDC_BeginJob(GDC_HANDLE *phHandle); + +/** + * @brief End a job,all tasks in the job will be submmitted to gdc + * + * @param hHandle(In), handle creat by CVI_GDC_BeginJob + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_GDC_EndJob(GDC_HANDLE hHandle); + +/** + * @brief Cancel a job ,then all tasks in the job will not be submmitted to gdc + * + * @param hHandle(In), handle creat by CVI_GDC_BeginJob + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_GDC_CancelJob(GDC_HANDLE hHandle); + +/** + * @brief Add a fisheye task to a gdc job + * + * @param hHandle(In), handle creat by CVI_GDC_BeginJob + * @param pstTask(In), GDC task attribute + * @param pstFisheyeAttr(In), for further settings + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_GDC_AddCorrectionTask(GDC_HANDLE hHandle, const GDC_TASK_ATTR_S *pstTask + , const FISHEYE_ATTR_S *pstFisheyeAttr); + +/** + * @brief Add a rotation task to a gdc job + * + * @param hHandle(In), handle creat by CVI_GDC_BeginJob + * @param pstTask(In), GDC task attribute + * @param enRotation(In), for further settings + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_GDC_AddRotationTask(GDC_HANDLE hHandle, const GDC_TASK_ATTR_S *pstTask, ROTATION_E enRotation); + +/** + * @brief Add a affine task to a gdc job + * + * @param hHandle(In), handle creat by CVI_GDC_BeginJob + * @param pstTask(In), GDC task attribute + * @param pstAffineAttr(In), for further settings + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_GDC_AddAffineTask(GDC_HANDLE hHandle, const GDC_TASK_ATTR_S *pstTask, const AFFINE_ATTR_S *pstAffineAttr); + +/** + * @brief Add a LDC task to a gdc job + * + * @param pstTask(In), GDC task attribute. + * @param pstLDCAttr(In), GDC LDC attribute + * @param enRotation(In), for further settings + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_GDC_AddLDCTask(GDC_HANDLE hHandle, const GDC_TASK_ATTR_S *pstTask + , const LDC_ATTR_S *pstLDCAttr, ROTATION_E enRotation); + +/** + * @brief this function is abandoned, do not support yet. + */ +CVI_S32 CVI_GDC_AddCnvWarpTask(const float *pfmesh_data, GDC_HANDLE hHandle, const GDC_TASK_ATTR_S *pstTask + , const FISHEYE_ATTR_S *pstAffineAttr, bool *bReNew); + +/** + * @brief this function is abandoned, do not support yet. + */ +CVI_S32 CVI_GDC_AddCorrectionTaskCNV(GDC_HANDLE hHandle, const GDC_TASK_ATTR_S *pstTask + , const FISHEYE_ATTR_S *pstFishEyeAttr, uint8_t *p_tbl, uint8_t *p_idl, uint32_t *tbl_param); + +/** + * @brief set meshsize for GDC + * + * @param nMeshHor(In), mesh counts horizontal + * @param nMeshVer(In), mesh counts vertical + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_GDC_SetMeshSize(int nMeshHor, int nMeshVer); + +/** + * @brief gen GDC LDC(Lens Distortion Correction) mesh table + * + * @param u32Width(In), mesh region width + * @param u32Height(In), mesh region height + * @param pstLDCAttr(In), GDC LDC attribute + * @param pu64PhyAddr(Out), mesh table physical addr in memory + * @param ppVirAddr(Out), mesh table virtual addr in memory + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_GDC_GenLDCMesh(CVI_U32 u32Width, CVI_U32 u32Height, const LDC_ATTR_S *pstLDCAttr + , const char *name, CVI_U64 *pu64PhyAddr, CVI_VOID **ppVirAddr); + +CVI_S32 CVI_GDC_LoadLDCMesh(CVI_U32 u32Width, CVI_U32 u32Height, const char *fileNname + , const char *tskName, CVI_U64 *pu64PhyAddr, CVI_VOID **ppVirAddr); + +/** + * @brief set GDC wrap buf attribute + * + * @param hHandle(In), handle creat by CVI_GDC_BeginJob + * @param pstTask(In), GDC task attribute + * @param pstBufWrap(In), GDC wrap buf attribute + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_GDC_SetBufWrapAttr(GDC_HANDLE hHandle, const GDC_TASK_ATTR_S *pstTask, const DWA_BUF_WRAP_S *pstBufWrap); + +/** + * @brief get GDC wrap buf attribute + * + * @param hHandle(In), handle creat by CVI_GDC_BeginJob + * @param pstTask(In), GDC task attribute + * @param pstBufWrap(Out), GDC wrap buf attribute + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_GDC_GetBufWrapAttr(GDC_HANDLE hHandle, const GDC_TASK_ATTR_S *pstTask, DWA_BUF_WRAP_S *pstBufWrap); + +/** + * @brief dump mesh data for GDC + * + * @param pMeshDumpAttr(In), mesh dump attribute + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_GDC_DumpMesh(MESH_DUMP_ATTR_S *pMeshDumpAttr); + +/** + * @brief load mesh for GDC, mesh data is load from user + * + * @param pMeshDumpAttr(In), mesh dump attribute + * @return CVI_S32 Return CVI_SUCCESS if succeed + */ +CVI_S32 CVI_GDC_LoadMesh(MESH_DUMP_ATTR_S *pMeshDumpAttr); +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* __CVI_GDC_H__ */ diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_mipi.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_mipi.h new file mode 100644 index 00000000..3531cdac --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_mipi.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved. + * + * File Name: include/cvi_mipi.h + * Description: + * Common mipi definitions. + */ + +#ifndef __CVI_MIPI_H__ +#define __CVI_MIPI_H__ + +#include + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* End of #ifdef __cplusplus */ + +typedef unsigned int combo_dev_t; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* __CVI_MIPI_H__ */ + diff --git a/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_misc.h b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_misc.h new file mode 100644 index 00000000..c0231d1e --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/include/cvi_misc.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) Cvitek Co., Ltd. 2019-2022. All rights reserved. + * + * File Name: include/cvi_misc.h + * Description: + * MMF Programe Interface for system + */ + + +#ifndef __CVI_MISC_H__ +#define __CVI_MISC_H__ + + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* End of #ifdef __cplusplus */ + +#include "cvi_debug.h" + +typedef enum { + CVI_EFUSE_AREA_USER, + CVI_EFUSE_AREA_DEVICE_ID, + CVI_EFUSE_AREA_HASH0_PUBLIC, + CVI_EFUSE_AREA_LOADER_EK, + CVI_EFUSE_AREA_DEVICE_EK, + CVI_EFUSE_AREA_CHIP_SN, + CVI_EFUSE_AREA_LAST +} CVI_EFUSE_AREA_E; + +typedef enum { + CVI_EFUSE_LOCK_HASH0_PUBLIC, + CVI_EFUSE_LOCK_LOADER_EK, + CVI_EFUSE_LOCK_DEVICE_EK, + CVI_EFUSE_LOCK_LAST +} CVI_EFUSE_LOCK_E; + +CVI_S32 CVI_MISC_GetChipSNSize(CVI_U32 *pu32SNSize); +CVI_S32 CVI_MISC_GetChipSN(CVI_U8 *pu8SN, CVI_U32 u32SNSize); + +CVI_S32 CVI_MISC_StartPMThread(void); +CVI_S32 CVI_MISC_StopPMThread(void); +/** 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/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/sample/audio/aac_sample/aacenc_interface.cpp b/components/3rd_party/sophgo-middleware/sophgo-middleware/v2/sample/audio/aac_sample/aacenc_interface.cpp new file mode 100644 index 00000000..02b7d948 --- /dev/null +++ b/components/3rd_party/sophgo-middleware/sophgo-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; /**