drivers/video/isx019: Fix white balance control and capability

This commit is contained in:
SPRESENSE 2022-10-24 22:40:27 +09:00 committed by Xiang Xiao
parent d57324473e
commit 5e4e8f6809

View File

@ -282,6 +282,7 @@ static int isx019_get_value(uint32_t id, uint32_t size,
static int isx019_set_value(uint32_t id, uint32_t size,
imgsensor_value_t value);
static int initialize_jpg_quality(void);
static void initialize_wbmode(void);
static int send_read_cmd(FAR struct i2c_config_s *config,
uint8_t cat,
uint16_t addr,
@ -770,7 +771,7 @@ int32_t g_isx019_wbmode[] =
* Private Functions
****************************************************************************/
int fpga_i2c_write(uint8_t addr, FAR uint8_t *data, uint8_t size)
static int fpga_i2c_write(uint8_t addr, FAR uint8_t *data, uint8_t size)
{
struct i2c_config_s config;
static uint8_t buf[FPGA_I2C_REGSIZE_MAX + FPGA_I2C_REGADDR_LEN];
@ -1211,6 +1212,7 @@ static int isx019_init(void)
power_on();
set_drive_mode();
fpga_init();
initialize_wbmode();
initialize_jpg_quality();
store_default_value();
clk = board_isx019_get_master_clock();
@ -1423,7 +1425,7 @@ static int activate_clip(imgsensor_stream_type_t type,
break;
default: /* 640 */
case 640:
if (clip->width == 640)
{
/* In this case, clip->height == 360 */
@ -1451,6 +1453,13 @@ static int activate_clip(imgsensor_stream_type_t type,
}
break;
default: /* Otherwise, clear clip setting. */
size = FPGA_CLIP_NON;
top = 0;
left = 0;
break;
}
fpga_i2c_write(FPGA_CLIP_SIZE, &size, 1);
@ -1512,30 +1521,27 @@ static int isx019_start_capture(imgsensor_stream_type_t type,
}
switch (fmt[IMGSENSOR_FMT_MAIN].width)
{
case 1280:
regval |= FPGA_SCALE_1280_960;
activate_clip(type,
fmt[IMGSENSOR_FMT_MAIN].width,
fmt[IMGSENSOR_FMT_MAIN].height);
break;
{
case 1280:
regval |= FPGA_SCALE_1280_960;
break;
case 640:
regval |= FPGA_SCALE_640_480;
activate_clip(type,
fmt[IMGSENSOR_FMT_MAIN].width,
fmt[IMGSENSOR_FMT_MAIN].height);
break;
case 640:
regval |= FPGA_SCALE_640_480;
break;
case 320:
regval |= FPGA_SCALE_320_240;
break;
case 320:
regval |= FPGA_SCALE_320_240;
break;
default: /* 160 */
default: /* 160 */
regval |= FPGA_SCALE_160_120;
break;
}
regval |= FPGA_SCALE_160_120;
break;
}
activate_clip(type,
fmt[IMGSENSOR_FMT_MAIN].width,
fmt[IMGSENSOR_FMT_MAIN].height);
fpga_i2c_write(FPGA_FORMAT_AND_SCALE, &regval, 1);
@ -1894,16 +1900,6 @@ static int32_t convert_hue_reg2is(int32_t val)
return (val * 128) / 90;
}
static int32_t convert_awb_is2reg(int32_t val)
{
return (val == 1) ? 0 : 2;
}
static int32_t convert_awb_reg2is(int32_t val)
{
return (val == 0) ? 1 : 0;
}
static int32_t convert_hdr_is2reg(int32_t val)
{
int32_t ret = AEWDMODE_AUTO;
@ -1985,11 +1981,6 @@ static convert_t get_reginfo(uint32_t id, bool is_set,
cvrt = is_set ? convert_hue_is2reg : convert_hue_reg2is;
break;
case IMGSENSOR_ID_AUTO_WHITE_BALANCE:
SET_REGINFO(reg, CAT_CATAWB, AWBMODE, 1);
cvrt = is_set ? convert_awb_is2reg : convert_awb_reg2is;
break;
case IMGSENSOR_ID_EXPOSURE:
SET_REGINFO(reg, CAT_AEDGRM, EVSEL, 1);
cvrt = not_convert;
@ -2147,7 +2138,18 @@ static int set_exptime(imgsensor_value_t val)
return isx019_i2c_write(CAT_CATAE, SHT_PRIMODE, (FAR uint8_t *)&regval, 4);
}
static int set_wbmode(imgsensor_value_t val)
static int set_awb_hold(void)
{
uint8_t mode = AWBMODE_HOLD;
return isx019_i2c_write(CAT_CATAWB, AWBMODE, &mode, 1);
}
static void initialize_wbmode(void)
{
g_isx019_private.wb_mode = IMGSENSOR_WHITE_BALANCE_AUTO;
}
static int update_wbmode_reg(int32_t val)
{
/* AWBMODE mode0 : auto, mode4 : user defined white balance
* AWBUSER_NO definition number for AWBMODE = mode4
@ -2175,7 +2177,7 @@ static int set_wbmode(imgsensor_value_t val)
toggle = true;
}
switch (val.value32)
switch (val)
{
case IMGSENSOR_WHITE_BALANCE_AUTO:
mode = AWBMODE_AUTO;
@ -2217,7 +2219,53 @@ static int set_wbmode(imgsensor_value_t val)
isx019_i2c_write(CAT_CATAWB, AWBUSER_NO, (FAR uint8_t *)&toggle, 1);
isx019_i2c_write(CAT_CATAWB, AWBMODE, &mode, 1);
return OK;
}
static bool is_awb_enable(void)
{
uint8_t mode = AWBMODE_AUTO;
isx019_i2c_read(CAT_CATAWB, AWBMODE, &mode, 1);
return mode != AWBMODE_HOLD;
}
static int set_wbmode(imgsensor_value_t val)
{
/* Update register only if IMGSENSOR_ID_AUTO_WHITE_BALANCE = 1. */
if (is_awb_enable())
{
update_wbmode_reg(val.value32);
}
g_isx019_private.wb_mode = val.value32;
return OK;
}
static int set_awb(imgsensor_value_t val)
{
/* true -> false : Update regster to HOLD
* false -> true : Update register
* with IMGSENSOR_ID_AUTO_N_PRESET_WB setting
* otherwise : Nothing to do
*/
if (is_awb_enable())
{
if (val.value32 == 0)
{
set_awb_hold();
}
}
else
{
if (val.value32 == 1)
{
update_wbmode_reg(g_isx019_private.wb_mode);
}
}
return OK;
}
@ -2644,6 +2692,10 @@ static setvalue_t set_value_func(uint32_t id)
func = set_exptime;
break;
case IMGSENSOR_ID_AUTO_WHITE_BALANCE:
func = set_awb;
break;
case IMGSENSOR_ID_AUTO_N_PRESET_WB:
func = set_wbmode;
break;
@ -2687,7 +2739,7 @@ static setvalue_t set_value_func(uint32_t id)
return func;
}
static int32_t get_flip(uint8_t *flip, uint8_t direction)
static int32_t get_flip(FAR uint8_t *flip, uint8_t direction)
{
DEBUGASSERT(flip);
@ -2782,6 +2834,18 @@ static int get_exptime(FAR imgsensor_value_t *val)
return OK;
}
static int get_awb(FAR imgsensor_value_t *val)
{
if (val == NULL)
{
return -EINVAL;
}
val->value32 = is_awb_enable();
return OK;
}
static int get_wbmode(FAR imgsensor_value_t *val)
{
if (val == NULL)
@ -3032,6 +3096,10 @@ static getvalue_t get_value_func(uint32_t id)
func = get_exptime;
break;
case IMGSENSOR_ID_AUTO_WHITE_BALANCE:
func = get_awb;
break;
case IMGSENSOR_ID_AUTO_N_PRESET_WB:
func = get_wbmode;
break;