#include #include #include #include #include #define ISP_DEBUG 0 // One camera accounts for 4k data #pragma pack(1) typedef struct tagsensor_isp_config_s { int sign; //id0: 0xAA66AA66, id1: 0xBB66BB66 int crc; //checksum, crc32 check, if crc = 0, do check int ver; //version, 0x01 int light_enable; //adc en, 1:use LIGHT_SENSOR_ATTR_S //ADC mode, 0:the brighter the u16LightValue more, 1:the brighter the u16LightValue smaller int adc_mode; //adc threshold: 1,adc_mode=0:smaller than it enter night mode, greater than it or equal enter day mode unsigned short light_def; //adc_mode=1:greater than it enter night mode, smaller than it or equal enter day mode; unsigned char ircut_state; //1:hold, 0:use ir_mode unsigned char res[4072]; /* noteFastboot specific for switching filesystems and systems */ unsigned char switch_system_flag; } SENSOR_ISP_CONFIGS_S; #pragma pack() #ifdef CFG_BOOT0_WRITE_IRSATTE_TO_ISP #if !defined(CFG_SUNXI_PHY_KEY) && !defined(CFG_GPADC_KEY) #error This function depends on gpadc #endif #define DEFAULT_COMPARISON_VALUE (1280) #define DAY_STATE 0 #define NIGHT_STATE 1 #define CAMERA1_SIGN (0xAA66AA66) #define CAMERA2_SIGN (0xBB66BB66) #define CAMERA1_ADC_CHANNEL (0) #define CAMERA2_ADC_CHANNEL (0) enum Day_Time { enum_none = 0, enum_day, enum_night, }; enum Led_Num { enum_ir_cut0 = 0, /* ir-cut- */ enum_ir_cut1, /* ir-cut+ */ enum_ir_led, enum_ir_count, }; enum Camera_Num { enum_camera0 = 0, enum_camera1, enum_camera_count, }; struct Camera_Param { int sign; int addr; int adc_channel; normal_gpio_cfg gpio_info[enum_ir_count]; }; struct Camera_Param camera_param[] = { [enum_camera0] = { .sign = CAMERA1_SIGN, .addr = CFG_ISPPARAM_LOAD_ADDR, .adc_channel = CAMERA1_ADC_CHANNEL, .gpio_info = { [enum_ir_cut0] = { .port = SUNXI_GPIO_D, .port_num = 18, .mul_sel = SUNXI_GPIO_OUTPUT, .pull = SUNXI_GPIO_PULL_DISABLE, .drv_level = SUNXI_GPIO_DRV_LEVEL1, .data = OUPUT_LOW_LEVEL, }, [enum_ir_cut1] = { .port = SUNXI_GPIO_D, .port_num = 8, .mul_sel = SUNXI_GPIO_OUTPUT, .pull = SUNXI_GPIO_PULL_DISABLE, .drv_level = SUNXI_GPIO_DRV_LEVEL1, .data = OUPUT_LOW_LEVEL, }, [enum_ir_led] = { .port = PORT_NO_USE, .port_num = PORT_NUM_NO_USE, .mul_sel = SUNXI_GPIO_OUTPUT, .pull = SUNXI_GPIO_PULL_DISABLE, .drv_level = SUNXI_GPIO_DRV_LEVEL1, .data = OUPUT_LOW_LEVEL, } } }, [enum_camera1] = { .sign = CAMERA2_SIGN, .addr = CFG_ISPPARAM_LOAD_ADDR + sizeof(SENSOR_ISP_CONFIGS_S), .adc_channel = CAMERA2_ADC_CHANNEL, .gpio_info = { [enum_ir_cut0] = { .port = SUNXI_GPIO_D, .port_num = 18, .mul_sel = SUNXI_GPIO_OUTPUT, .pull = SUNXI_GPIO_PULL_DISABLE, .drv_level = SUNXI_GPIO_DRV_LEVEL1, .data = OUPUT_LOW_LEVEL, }, [enum_ir_cut1] = { .port = SUNXI_GPIO_D, .port_num = 8, .mul_sel = SUNXI_GPIO_OUTPUT, .pull = SUNXI_GPIO_PULL_DISABLE, .drv_level = SUNXI_GPIO_DRV_LEVEL1, .data = OUPUT_LOW_LEVEL, }, [enum_ir_led] = { .port = PORT_NO_USE, .port_num = PORT_NUM_NO_USE, .mul_sel = SUNXI_GPIO_OUTPUT, .pull = SUNXI_GPIO_PULL_DISABLE, .drv_level = SUNXI_GPIO_DRV_LEVEL1, .data = OUPUT_LOW_LEVEL, } } } }; #ifdef CFG_SUNXI_FDT extern int sprintf(char *buf, const char *fmt, ...); #define FDT_PATH_ISP_INIT_GPIO "/soc/isp_boot0_gpio" int select_isp_param_from_dts(void) { int nodeoffset; char isp_gpioparam_str[16] = { 0 }; pr_emerg("get info from dts:%d\n", __LINE__); nodeoffset = fdt_path_offset(working_fdt, FDT_PATH_ISP_INIT_GPIO); if (nodeoffset < 0) { return 0; } if (!fdtdec_get_is_enabled(working_fdt, nodeoffset)) { return 0; } for (int i = enum_camera0; i < enum_camera_count; i++) { sprintf(isp_gpioparam_str, "camera%d_cut0\0", enum_camera0); fdt_get_one_gpio( FDT_PATH_ISP_INIT_GPIO, isp_gpioparam_str, &camera_param[enum_camera0].gpio_info[enum_ir_cut0]); sprintf(isp_gpioparam_str, "camera%d_cut1\0", enum_camera0); fdt_get_one_gpio( FDT_PATH_ISP_INIT_GPIO, isp_gpioparam_str, &camera_param[enum_camera0].gpio_info[enum_ir_cut1]); sprintf(isp_gpioparam_str, "camera%d_led\0", enum_camera0); fdt_get_one_gpio( FDT_PATH_ISP_INIT_GPIO, isp_gpioparam_str, &camera_param[enum_camera0].gpio_info[enum_ir_count]); } return 0; } #endif void ctrl_led_for_isp(normal_gpio_cfg gpio_info[], enum Day_Time day_time) { switch (day_time) { case enum_none: gpio_info[enum_ir_cut0].data = OUPUT_LOW_LEVEL; gpio_info[enum_ir_cut1].data = OUPUT_HIGH_LEVEL; gpio_info[enum_ir_led].data = OUPUT_LOW_LEVEL; boot_set_gpio_new(gpio_info, enum_ir_count, 1); break; case enum_day: gpio_info[enum_ir_cut0].data = OUPUT_HIGH_LEVEL; gpio_info[enum_ir_cut1].data = OUPUT_LOW_LEVEL; gpio_info[enum_ir_led].data = OUPUT_LOW_LEVEL; boot_set_gpio_new(gpio_info, enum_ir_count, 1); break; case enum_night: gpio_info[enum_ir_cut0].data = OUPUT_LOW_LEVEL; gpio_info[enum_ir_cut1].data = OUPUT_HIGH_LEVEL; gpio_info[enum_ir_led].data = OUPUT_HIGH_LEVEL; boot_set_gpio_new(gpio_info, enum_ir_count, 1); break; default: printf("Input time error\n"); break; } } enum Day_Time get_day_or_night(unsigned int vol, int adc_mode, unsigned short light_def) { int temp_light_def = light_def; enum Day_Time day_time; if (!temp_light_def) temp_light_def = DEFAULT_COMPARISON_VALUE; if (adc_mode) { // the brighter the u16LightValue smaller if (vol > temp_light_def) { day_time = enum_night; } else { day_time = enum_day; } } else { if (vol > temp_light_def) { day_time = enum_day; } else { day_time = enum_night; } } return day_time; } int update_camera_param(struct Camera_Param camera_param) { /* day--1 night--2*/ enum Day_Time day_time = 0; unsigned int vol = 0; SENSOR_ISP_CONFIGS_S *ispconfig_param = (SENSOR_ISP_CONFIGS_S *)(camera_param.addr); //sign check if (ispconfig_param->sign != camera_param.sign) { printf("camera sign error:0x%x\n", ispconfig_param->sign); return -1; } if (ispconfig_param->light_enable != 1) { printf("no use isp light\n"); return -1; } extern int sunxi_read_gpadc_vol(int channel); vol = sunxi_read_gpadc_vol(camera_param.adc_channel); printf("gpadc val:%d\n", vol); day_time = get_day_or_night(vol, ispconfig_param->adc_mode, ispconfig_param->light_def); ctrl_led_for_isp(camera_param.gpio_info, day_time); ispconfig_param->ircut_state = day_time; #if ISP_DEBUG printf("=======================================>\n"); printf("ispconfig_param addr = 0x%x\n", ispconfig_param); printf("ispconfig_param->sign = 0x%x\n", ispconfig_param->sign); printf("ispconfig_param->light_enable = 0x%x\n", ispconfig_param->light_enable); printf("ispconfig_param->adc_mode = 0x%x\n", ispconfig_param->adc_mode); printf("ispconfig_param->light_def = 0x%x\n", ispconfig_param->light_def); printf("ispconfig_param->ircut_state = 0x%x\n", ispconfig_param->ircut_state); printf("===========================================\n"); #endif return 0; } void update_ir_state(void) { for (int i = enum_camera0; i < enum_camera_count; i++) { update_camera_param(camera_param[i]); } #if ISP_DEBUG /* dump camera_param*/ for (int i = enum_camera0; i < enum_camera_count; i++) { printf("camera %d\nsign:0x%x\n", i, camera_param[i].sign); printf("addr:0x%x\n", camera_param[i].sign); printf("adc_channel:0x%x\n", camera_param[i].adc_channel); printf("enum_ir_cut0\nport :0x%x port_num:0x%x\nmul_sel:0x%x " "pull:0x%x drv_level:0x%x\ndata:0x%x\n", camera_param[i].gpio_info[enum_ir_cut0].port, camera_param[i].gpio_info[enum_ir_cut0].port_num, camera_param[i].gpio_info[enum_ir_cut0].mul_sel, camera_param[i].gpio_info[enum_ir_cut0].pull, camera_param[i].gpio_info[enum_ir_cut0].drv_level, camera_param[i].gpio_info[enum_ir_cut0].data); printf("enum_ir_cut1\nport :0x%x port_num:0x%x\nmul_sel:0x%x " "pull:0x%x drv_level:0x%x\ndata:0x%x\n", camera_param[i].gpio_info[enum_ir_cut1].port, camera_param[i].gpio_info[enum_ir_cut1].port_num, camera_param[i].gpio_info[enum_ir_cut1].mul_sel, camera_param[i].gpio_info[enum_ir_cut1].pull, camera_param[i].gpio_info[enum_ir_cut1].drv_level, camera_param[i].gpio_info[enum_ir_cut1].data); printf("enum_ir_led\nport :0x%x port_num:0x%x\nmul_sel:0x%x " "pull:0x%x drv_level:0x%x\ndata:0x%x\n", camera_param[i].gpio_info[enum_ir_led].port, camera_param[i].gpio_info[enum_ir_led].port_num, camera_param[i].gpio_info[enum_ir_led].mul_sel, camera_param[i].gpio_info[enum_ir_led].pull, camera_param[i].gpio_info[enum_ir_led].drv_level, camera_param[i].gpio_info[enum_ir_led].data); } #endif } #endif #ifndef CFG_SUNXI_ENV /* flag is placed in the last byte of the last region */ unsigned char read_switch_flag_from_kernel(void) { /* camera 1*/ SENSOR_ISP_CONFIGS_S *ispconfig_param = (SENSOR_ISP_CONFIGS_S *)(CFG_ISPPARAM_LOAD_ADDR + sizeof(SENSOR_ISP_CONFIGS_S)); printf("switch_system_flag value:0x%x\n", ispconfig_param->switch_system_flag); return ispconfig_param->switch_system_flag; } #endif void update_isp_param(void) { #ifdef CFG_BOOT0_WRITE_IRSATTE_TO_ISP #ifdef CFG_SUNXI_FDT select_isp_param_from_dts(); #endif //CFG_SUNXI_FDT update_ir_state(); #endif /*CFG_BOOT0_WRITE_IRSATTE_TO_ISP*/ }