Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

video: drivers misc fixes #87366

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Prev Previous commit
Next Next commit
drivers: video: ov5640: Fix gain controls
Separate autogain and gain controls. This type of controls depend on
each other and  will be supported as "control group" in the new video
control framework.

Signed-off-by: Trung Hieu Le <trunghieu.le@nxp.com>
Signed-off-by: Phi Bang Nguyen <phibang.nguyen@nxp.com>
trunghieulenxp authored and ngphibang committed Mar 21, 2025
commit db294171ec7e8f1dc1f22a64ec929ea72ac4781f
36 changes: 24 additions & 12 deletions drivers/video/ov5640.c
Original file line number Diff line number Diff line change
@@ -146,6 +146,7 @@ struct ov5640_data {
uint32_t cur_pixrate;
uint16_t cur_frmrate;
const struct ov5640_mode_config *cur_mode;
bool auto_gain;
};

static const struct ov5640_reg init_params_common[] = {
@@ -997,25 +998,34 @@ static int ov5640_set_ctrl_contrast(const struct device *dev, int value)
static int ov5640_set_ctrl_gain(const struct device *dev, int value)
{
const struct ov5640_config *cfg = dev->config;
struct ov5640_data *data = dev->data;

if (!IN_RANGE(value, 0, UINT16_MAX)) {
if (data->auto_gain) {
return -ENOTSUP;
}

if (!IN_RANGE(value, 0, 1023)) {
return -EINVAL;
}

if (value) {
int ret = ov5640_modify_reg(&cfg->i2c, AEC_PK_MANUAL, BIT(1), BIT(0));
int ret = ov5640_modify_reg(&cfg->i2c, AEC_PK_REAL_GAIN, 0x03, (value >> 8) & 0x03);

if (ret) {
return ret;
}
if (ret) {
return ret;
}

struct ov5640_reg gain_params[] = {{AEC_PK_REAL_GAIN, value >> 8},
{AEC_PK_REAL_GAIN + 1, value & 0xff}};
ret = ov5640_write_reg(&cfg->i2c, AEC_PK_REAL_GAIN + 1, value & 0xff);
return ret;
}

return ov5640_write_multi_regs(&cfg->i2c, gain_params, ARRAY_SIZE(gain_params));
} else {
return ov5640_write_reg(&cfg->i2c, AEC_PK_MANUAL, 0);
}
static int ov5640_set_ctrl_autogain(const struct device *dev, bool value)
{
const struct ov5640_config *cfg = dev->config;
struct ov5640_data *data = dev->data;

data->auto_gain = value;

return ov5640_modify_reg(&cfg->i2c, AEC_PK_MANUAL, BIT(1), data->auto_gain ? 0 : BIT(1));
}

static int ov5640_set_ctrl_hflip(const struct device *dev, int value)
@@ -1073,6 +1083,8 @@ static int ov5640_set_ctrl(const struct device *dev, unsigned int cid, void *val
return ov5640_set_ctrl_brightness(dev, (int)(value));
case VIDEO_CID_CONTRAST:
return ov5640_set_ctrl_contrast(dev, (int)value);
case VIDEO_CID_AUTOGAIN:
return ov5640_set_ctrl_autogain(dev, (bool)(value));
case VIDEO_CID_GAIN:
return ov5640_set_ctrl_gain(dev, (int)(value));
case VIDEO_CID_HFLIP:
3 changes: 3 additions & 0 deletions include/zephyr/drivers/video-controls.h
Original file line number Diff line number Diff line change
@@ -54,6 +54,9 @@ extern "C" {
/** Amount of time an image sensor is exposed to light, affecting the brightness */
#define VIDEO_CID_EXPOSURE (VIDEO_CID_BASE + 17)

/** Enable/Disable the autogain */
#define VIDEO_CID_AUTOGAIN (VIDEO_CID_BASE + 18)

/** Amount of amplification performed to each pixel electrical signal, affecting the brightness */
#define VIDEO_CID_GAIN (VIDEO_CID_BASE + 19)