sdk-hwV1.3/lichee/brandy-2.0/spl/common/update_ispparm.c

330 lines
9.3 KiB
C

#include <common.h>
#include <arch/gpio.h>
#include <spare_head.h>
#include <arch/gpio_new.h>
#include <libfdt.h>
#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*/
}