diff --git a/drivers/video/ov2640.c b/drivers/video/ov2640.c index 34038ba0ed3a6..5ebbbeccaab86 100644 --- a/drivers/video/ov2640.c +++ b/drivers/video/ov2640.c @@ -957,7 +957,7 @@ static int ov2640_set_ctrl(const struct device *dev, case VIDEO_CID_CAMERA_CONTRAST: ret |= ov2640_set_contrast(dev, (int)value); break; - case VIDEO_CID_CAMERA_COLORBAR: + case VIDEO_CID_CAMERA_TEST_PATTERN: ret |= ov2640_set_colorbar(dev, (int)value); break; case VIDEO_CID_CAMERA_QUALITY: diff --git a/drivers/video/ov5640.c b/drivers/video/ov5640.c index d5ee05a66b000..f02b5b3d1dbc8 100644 --- a/drivers/video/ov5640.c +++ b/drivers/video/ov5640.c @@ -7,6 +7,8 @@ #define DT_DRV_COMPAT ovti_ov5640 #include +#include +#include #include #include #include @@ -33,8 +35,10 @@ LOG_MODULE_REGISTER(video_ov5640, CONFIG_VIDEO_LOG_LEVEL); #define SCCB_SYS_CTRL1_REG 0x3103 #define TIMING_TC_REG20_REG 0x3820 #define TIMING_TC_REG21_REG 0x3821 +#define HZ5060_CTRL00_REG 0x3c00 #define HZ5060_CTRL01_REG 0x3c01 #define ISP_CTRL01_REG 0x5001 +#define PRE_ISP_TEST_SET1 0x503d #define SC_PLL_CTRL0_REG 0x3034 #define SC_PLL_CTRL1_REG 0x3035 @@ -43,13 +47,15 @@ LOG_MODULE_REGISTER(video_ov5640, CONFIG_VIDEO_LOG_LEVEL); #define SYS_ROOT_DIV_REG 0x3108 #define PCLK_PERIOD_REG 0x4837 -#define AEC_CTRL00_REG 0x3a00 -#define AEC_CTRL0F_REG 0x3a0f -#define AEC_CTRL10_REG 0x3a10 -#define AEC_CTRL11_REG 0x3a11 -#define AEC_CTRL1B_REG 0x3a1b -#define AEC_CTRL1E_REG 0x3a1e -#define AEC_CTRL1F_REG 0x3a1f +#define AEC_PK_REAL_GAIN 0x350a +#define AEC_PK_MANUAL 0x3503 +#define AEC_CTRL00_REG 0x3a00 +#define AEC_CTRL0F_REG 0x3a0f +#define AEC_CTRL10_REG 0x3a10 +#define AEC_CTRL11_REG 0x3a11 +#define AEC_CTRL1B_REG 0x3a1b +#define AEC_CTRL1E_REG 0x3a1e +#define AEC_CTRL1F_REG 0x3a1f #define BLC_CTRL01_REG 0x4001 #define BLC_CTRL04_REG 0x4004 @@ -71,15 +77,37 @@ LOG_MODULE_REGISTER(video_ov5640, CONFIG_VIDEO_LOG_LEVEL); #define AWB_CTRL30_REG 0x519e #define SDE_CTRL0_REG 0x5580 +#define SDE_CTRL1_REG 0x5581 +#define SDE_CTRL2_REG 0x5582 #define SDE_CTRL3_REG 0x5583 #define SDE_CTRL4_REG 0x5584 +#define SDE_CTRL5_REG 0x5585 +#define SDE_CTRL6_REG 0x5586 +#define SDE_CTRL7_REG 0x5587 +#define SDE_CTRL8_REG 0x5588 #define SDE_CTRL9_REG 0x5589 #define SDE_CTRL10_REG 0x558a #define SDE_CTRL11_REG 0x558b #define DEFAULT_MIPI_CHANNEL 0 -#define OV5640_RESOLUTION_PARAM_NUM 24 +#define PI 3.141592654 + +#define ABS(a, b) (a > b ? a - b : b - a) + +#define PCLK_ROOT_DIV 1 +#define SCLK2X_DIV 1 +#define SCLK_DIV 2 +#define PLL_ROOT_DIV 2 +#define PLL_PRE_DIV 3 +#define MIPI_BIT_MODE 0x08 + +/* Must be kept in ascending order */ +enum ov5640_frame_rate { + OV5640_15_FPS = 15, + OV5640_30_FPS = 30, + OV5640_60_FPS = 60, +}; struct ov5640_config { struct i2c_dt_spec i2c; @@ -87,28 +115,35 @@ struct ov5640_config { struct gpio_dt_spec powerdown_gpio; }; -struct ov5640_data { - struct video_format fmt; -}; - struct ov5640_reg { uint16_t addr; uint8_t val; }; -struct ov5640_mipi_clock_config { +struct ov5640_mipi_frmrate_config { + uint8_t frmrate; uint8_t pllCtrl1; uint8_t pllCtrl2; + uint32_t pixelrate; }; -struct ov5640_resolution_config { +struct ov5640_mode_config { uint16_t width; uint16_t height; const struct ov5640_reg *res_params; - const struct ov5640_mipi_clock_config mipi_pclk; + const struct ov5640_mipi_frmrate_config *mipi_frmrate_config; + uint16_t max_frmrate; + uint16_t def_frmrate; +}; + +struct ov5640_data { + struct video_format fmt; + uint64_t cur_pixrate; + uint16_t cur_frmrate; + const struct ov5640_mode_config *cur_mode; }; -static const struct ov5640_reg ov5640InitParams[] = { +static const struct ov5640_reg init_params[] = { /* Power down */ {SYS_CTRL0_REG, SYS_CTRL0_SW_PWDN}, @@ -323,36 +358,45 @@ static const struct ov5640_reg ov5640InitParams[] = { {0x5000, 0xa7}, }; -static const struct ov5640_reg ov5640_low_res_params[] = { +static const struct ov5640_reg low_res_params[] = { {0x3800, 0x00}, {0x3801, 0x00}, {0x3802, 0x00}, {0x3803, 0x04}, {0x3804, 0x0a}, {0x3805, 0x3f}, {0x3806, 0x07}, {0x3807, 0x9b}, {0x3808, 0x02}, {0x3809, 0x80}, {0x380a, 0x01}, {0x380b, 0xe0}, {0x380c, 0x07}, {0x380d, 0x68}, {0x380e, 0x03}, {0x380f, 0xd8}, {0x3810, 0x00}, {0x3811, 0x10}, {0x3812, 0x00}, {0x3813, 0x06}, {0x3814, 0x31}, {0x3815, 0x31}, {0x3824, 0x02}, {0x460c, 0x22}}; -static const struct ov5640_reg ov5640_720p_res_params[] = { +static const struct ov5640_reg hd_res_params[] = { {0x3800, 0x00}, {0x3801, 0x00}, {0x3802, 0x00}, {0x3803, 0xfa}, {0x3804, 0x0a}, {0x3805, 0x3f}, {0x3806, 0x06}, {0x3807, 0xa9}, {0x3808, 0x05}, {0x3809, 0x00}, {0x380a, 0x02}, {0x380b, 0xd0}, {0x380c, 0x07}, {0x380d, 0x64}, {0x380e, 0x02}, {0x380f, 0xe4}, {0x3810, 0x00}, {0x3811, 0x10}, {0x3812, 0x00}, {0x3813, 0x04}, {0x3814, 0x31}, {0x3815, 0x31}, {0x3824, 0x04}, {0x460c, 0x20}}; -static const struct ov5640_resolution_config resolutionParams[] = { - {.width = 640, - .height = 480, - .res_params = ov5640_low_res_params, - .mipi_pclk = { - .pllCtrl1 = 0x14, - .pllCtrl2 = 0x38, - }}, - {.width = 1280, - .height = 720, - .res_params = ov5640_720p_res_params, - .mipi_pclk = { - .pllCtrl1 = 0x21, - .pllCtrl2 = 0x54, - }}, -}; +static const struct ov5640_mipi_frmrate_config mipi_hd_frmrate_params[] = { + {15, 0x21, 0x2A, 24000000}, {30, 0x21, 0x54, 48000000}, {60, 0x11, 0x54, 96000000}}; + +static const struct ov5640_mipi_frmrate_config mipi_vga_frmrate_params[] = { + {15, 0x22, 0x38, 24000000}, {30, 0x14, 0x38, 24000000}, {60, 0x14, 0x70, 48000000}}; + +static const struct ov5640_mode_config modes[] = { + { + .width = 640, + .height = 480, + .res_params = low_res_params, + .mipi_frmrate_config = mipi_vga_frmrate_params, + .max_frmrate = OV5640_60_FPS, + .def_frmrate = OV5640_30_FPS, + }, + { + .width = 1280, + .height = 720, + .res_params = hd_res_params, + .mipi_frmrate_config = mipi_hd_frmrate_params, + .max_frmrate = OV5640_60_FPS, + .def_frmrate = OV5640_30_FPS, + }}; + +static const int ov5640_frame_rates[] = {OV5640_15_FPS, OV5640_30_FPS, OV5640_60_FPS}; #define OV5640_VIDEO_FORMAT_CAP(width, height, format) \ { \ @@ -455,13 +499,62 @@ static int ov5640_write_multi_regs(const struct i2c_dt_spec *spec, const struct return 0; } +static int ov5640_set_frmival(const struct device *dev, enum video_endpoint_id ep, + struct video_frmival *frmival) +{ + const struct ov5640_config *cfg = dev->config; + struct ov5640_data *drv_data = dev->data; + int ret; + uint8_t i, ind = 0; + uint32_t desired_frmrate, best_match = ov5640_frame_rates[ind]; + + desired_frmrate = DIV_ROUND_CLOSEST(frmival->denominator, frmival->numerator); + + /* Find the supported frame rate closest to the desired one */ + for (i = 0; i < ARRAY_SIZE(ov5640_frame_rates); i++) { + if (ov5640_frame_rates[i] <= drv_data->cur_mode->max_frmrate && + ABS(desired_frmrate, ov5640_frame_rates[i]) < + ABS(desired_frmrate, best_match)) { + best_match = ov5640_frame_rates[i]; + ind = i; + } + } + + struct ov5640_reg frmrate_params[] = { + {SC_PLL_CTRL1_REG, drv_data->cur_mode->mipi_frmrate_config[ind].pllCtrl1}, + {SC_PLL_CTRL2_REG, drv_data->cur_mode->mipi_frmrate_config[ind].pllCtrl2}, + {PCLK_PERIOD_REG, 0x0a}}; + + ret = ov5640_write_multi_regs(&cfg->i2c, frmrate_params, ARRAY_SIZE(frmrate_params)); + ret |= ov5640_modify_reg(&cfg->i2c, SC_PLL_CTRL0_REG, 0x0f, MIPI_BIT_MODE); + ret |= ov5640_modify_reg(&cfg->i2c, SC_PLL_CTRL3_REG, 0x1f, + (LOG2CEIL(PLL_ROOT_DIV) << 4) | (PLL_PRE_DIV & 0x07)); + ret |= ov5640_modify_reg(&cfg->i2c, SYS_ROOT_DIV_REG, 0x3f, + (LOG2CEIL(PCLK_ROOT_DIV) & 0x03 << 4) | + (LOG2CEIL(SCLK2X_DIV) & 0x03 << 2) | + (LOG2CEIL(SCLK_DIV) & 0x03)); + + if (ret) { + LOG_ERR("Unable to set frame interval"); + return ret; + } + + drv_data->cur_frmrate = best_match; + drv_data->cur_pixrate = drv_data->cur_mode->mipi_frmrate_config[ind].pixelrate; + + frmival->numerator = 1; + frmival->denominator = best_match; + + return 0; +} + static int ov5640_set_fmt(const struct device *dev, enum video_endpoint_id ep, struct video_format *fmt) { struct ov5640_data *drv_data = dev->data; const struct ov5640_config *cfg = dev->config; - int ret; - int i; + int ret, i; + struct video_frmival def_frmival; for (i = 0; i < ARRAY_SIZE(fmts); ++i) { if (fmt->pixelformat == fmts[i].pixelformat && fmt->width >= fmts[i].width_min && @@ -482,22 +575,25 @@ static int ov5640_set_fmt(const struct device *dev, enum video_endpoint_id ep, drv_data->fmt = *fmt; - /* Set resolution parameters */ - for (i = 0; i < ARRAY_SIZE(resolutionParams); i++) { - if (fmt->width == resolutionParams[i].width && - fmt->height == resolutionParams[i].height) { - ret = ov5640_write_multi_regs(&cfg->i2c, resolutionParams[i].res_params, - OV5640_RESOLUTION_PARAM_NUM); + /* Set resolution */ + for (i = 0; i < ARRAY_SIZE(modes); i++) { + if (fmt->width == modes[i].width && fmt->height == modes[i].height) { + ret = ov5640_write_multi_regs(&cfg->i2c, modes[i].res_params, + modes[i].res_params == hd_res_params + ? ARRAY_SIZE(hd_res_params) + : ARRAY_SIZE(low_res_params)); if (ret) { LOG_ERR("Unable to set resolution parameters"); return ret; } + + drv_data->cur_mode = &modes[i]; break; } } - /* Set pixel format, default to VIDEO_PIX_FMT_RGB565 */ - struct ov5640_reg fmt_params[2] = { + /* Set pixel format */ + struct ov5640_reg fmt_params[] = { {0x4300, 0x6f}, {0x501f, 0x01}, }; @@ -513,21 +609,11 @@ static int ov5640_set_fmt(const struct device *dev, enum video_endpoint_id ep, return ret; } - /* Configure MIPI pixel clock */ - ret |= ov5640_modify_reg(&cfg->i2c, SC_PLL_CTRL0_REG, 0x0f, 0x08); - ret |= ov5640_modify_reg(&cfg->i2c, SC_PLL_CTRL1_REG, 0xff, - resolutionParams[i].mipi_pclk.pllCtrl1); - ret |= ov5640_modify_reg(&cfg->i2c, SC_PLL_CTRL2_REG, 0xff, - resolutionParams[i].mipi_pclk.pllCtrl2); - ret |= ov5640_modify_reg(&cfg->i2c, SC_PLL_CTRL3_REG, 0x1f, 0x13); - ret |= ov5640_modify_reg(&cfg->i2c, SYS_ROOT_DIV_REG, 0x3f, 0x01); - ret |= ov5640_write_reg(&cfg->i2c, PCLK_PERIOD_REG, 0x0a); - if (ret) { - LOG_ERR("Unable to configure MIPI pixel clock"); - return ret; - } + /* Set frame rate */ + def_frmival.denominator = drv_data->cur_mode->def_frmrate; + def_frmival.numerator = 1; - return 0; + return ov5640_set_frmival(dev, ep, &def_frmival); } static int ov5640_get_fmt(const struct device *dev, enum video_endpoint_id ep, @@ -573,12 +659,273 @@ static int ov5640_stream_stop(const struct device *dev) return ov5640_write_reg(&cfg->i2c, SYS_CTRL0_REG, SYS_CTRL0_SW_PWDN); } +#define TEST_PATTERN_ENABLE BIT(7) +#define TEST_PATTERN_ROLLING BIT(6) +#define TEST_PATTERN_BAR (0 << 0) +#define TEST_PATTERN_SQUARE (2 << 0) + +static const uint8_t test_pattern_val[] = { + 0, + TEST_PATTERN_ENABLE | TEST_PATTERN_BAR | (1 << 2), + TEST_PATTERN_ENABLE | TEST_PATTERN_BAR | (1 << 2) | TEST_PATTERN_ROLLING, + TEST_PATTERN_ENABLE | TEST_PATTERN_SQUARE, + TEST_PATTERN_ENABLE | TEST_PATTERN_SQUARE | TEST_PATTERN_ROLLING, +}; + +static int ov5640_set_ctrl_test_pattern(const struct device *dev, int value) +{ + const struct ov5640_config *cfg = dev->config; + + if (!IN_RANGE(value, 0, ARRAY_SIZE(test_pattern_val) - 1)) { + return -EINVAL; + } + + return ov5640_write_reg(&cfg->i2c, PRE_ISP_TEST_SET1, test_pattern_val[value]); +} + +static int ov5640_set_ctrl_hue(const struct device *dev, int value) +{ + const struct ov5640_config *cfg = dev->config; + int cos_coef, sin_coef, sign = 0; + + if (!IN_RANGE(value, 0, 360)) { + return -EINVAL; + } + + double rad_val = value; + int ret = ov5640_modify_reg(&cfg->i2c, SDE_CTRL0_REG, BIT(0), BIT(0)); + + if (ret) { + return ret; + } + + rad_val = value * PI / 180.0; + cos_coef = round(cos(rad_val) * 128); + sin_coef = round(sin(rad_val) * 128); + + if (0 <= value && value < 90) { + sign = 0x01; + } else if (90 <= value && value < 180) { + sign = 0x31; + } else if (180 <= value && value < 270) { + sign = 0x32; + } else if (270 <= value && value < 360) { + sign = 0x02; + } + + struct ov5640_reg hue_params[] = {{SDE_CTRL8_REG, sign}, + {SDE_CTRL1_REG, abs(cos_coef)}, + {SDE_CTRL2_REG, abs(sin_coef)}}; + + return ov5640_write_multi_regs(&cfg->i2c, hue_params, ARRAY_SIZE(hue_params)); +} + +static int ov5640_set_ctrl_saturation(const struct device *dev, int value) +{ + const struct ov5640_config *cfg = dev->config; + + if (!IN_RANGE(value, 0, UINT8_MAX)) { + return -EINVAL; + } + + struct ov5640_reg saturation_params[] = {{SDE_CTRL3_REG, value}, {SDE_CTRL4_REG, value}}; + int ret = ov5640_modify_reg(&cfg->i2c, SDE_CTRL8_REG, BIT(6) | BIT(0), BIT(6) | BIT(0)); + + if (ret) { + return ret; + } + + return ov5640_write_multi_regs(&cfg->i2c, saturation_params, ARRAY_SIZE(saturation_params)); +} + +static int ov5640_set_ctrl_brightness(const struct device *dev, int value) +{ + const struct ov5640_config *cfg = dev->config; + + if (!IN_RANGE(value, -UINT8_MAX, UINT8_MAX)) { + return -EINVAL; + } + + struct ov5640_reg brightness_params[] = {{SDE_CTRL8_REG, value >= 0 ? 0x01 : 0x09}, + {SDE_CTRL7_REG, abs(value) & 0xff}}; + int ret = ov5640_modify_reg(&cfg->i2c, SDE_CTRL0_REG, BIT(2), BIT(2)); + + if (ret) { + return ret; + } + + return ov5640_write_multi_regs(&cfg->i2c, brightness_params, ARRAY_SIZE(brightness_params)); +} + +static int ov5640_set_ctrl_contrast(const struct device *dev, int value) +{ + const struct ov5640_config *cfg = dev->config; + + if (!IN_RANGE(value, 0, UINT8_MAX)) { + return -EINVAL; + } + + int ret = ov5640_modify_reg(&cfg->i2c, SDE_CTRL0_REG, BIT(2), BIT(2)); + + if (ret) { + return ret; + } + + return ov5640_write_reg(&cfg->i2c, SDE_CTRL6_REG, value & 0xff); +} + +static int ov5640_set_ctrl_gain(const struct device *dev, int value) +{ + const struct ov5640_config *cfg = dev->config; + + if (!IN_RANGE(value, 0, UINT16_MAX)) { + return -EINVAL; + } + + if (value) { + int ret = ov5640_modify_reg(&cfg->i2c, AEC_PK_MANUAL, BIT(1), BIT(0)); + + if (ret) { + return ret; + } + + struct ov5640_reg gain_params[] = {{AEC_PK_REAL_GAIN, value >> 8}, + {AEC_PK_REAL_GAIN + 1, value & 0xff}}; + + 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_hflip(const struct device *dev, int value) +{ + const struct ov5640_config *cfg = dev->config; + + return ov5640_modify_reg(&cfg->i2c, TIMING_TC_REG21_REG, BIT(2) | BIT(1), + value ? 0 : BIT(2) | BIT(1)); +} + +static int ov5640_set_ctrl_vflip(const struct device *dev, int value) +{ + const struct ov5640_config *cfg = dev->config; + + return ov5640_modify_reg(&cfg->i2c, TIMING_TC_REG20_REG, BIT(2) | BIT(1), + value ? BIT(2) | BIT(1) : 0); +} + +static int ov5640_set_ctrl_power_line_freq(const struct device *dev, int value) +{ + const struct ov5640_config *cfg = dev->config; + int ret; + + switch (value) { + case VIDEO_CID_POWER_LINE_FREQUENCY_AUTO: + ret = ov5640_modify_reg(&cfg->i2c, HZ5060_CTRL01_REG, BIT(7), 0); + return ret; + case VIDEO_CID_POWER_LINE_FREQUENCY_50HZ: + ret = ov5640_modify_reg(&cfg->i2c, HZ5060_CTRL00_REG, BIT(2), BIT(2)); + break; + case VIDEO_CID_POWER_LINE_FREQUENCY_60HZ: + ret = ov5640_modify_reg(&cfg->i2c, HZ5060_CTRL00_REG, BIT(2), 0); + break; + default: + return -EINVAL; + } + + if (ret) { + return ret; + } + + return ov5640_modify_reg(&cfg->i2c, HZ5060_CTRL01_REG, BIT(7), BIT(7)); +} + +static int ov5640_set_ctrl(const struct device *dev, unsigned int cid, void *value) +{ + switch (cid) { + case VIDEO_CID_CAMERA_TEST_PATTERN: + return ov5640_set_ctrl_test_pattern(dev, (int)value); + case VIDEO_CID_CAMERA_HUE: + return ov5640_set_ctrl_hue(dev, (int)value); + case VIDEO_CID_CAMERA_SATURATION: + return ov5640_set_ctrl_saturation(dev, (int)(value)); + case VIDEO_CID_CAMERA_BRIGHTNESS: + return ov5640_set_ctrl_brightness(dev, (int)(value)); + case VIDEO_CID_CAMERA_CONTRAST: + return ov5640_set_ctrl_contrast(dev, (int)value); + case VIDEO_CID_CAMERA_GAIN: + return ov5640_set_ctrl_gain(dev, (int)(value)); + case VIDEO_CID_HFLIP: + return ov5640_set_ctrl_hflip(dev, (int)(value)); + case VIDEO_CID_VFLIP: + return ov5640_set_ctrl_vflip(dev, (int)(value)); + case VIDEO_CID_POWER_LINE_FREQUENCY: + return ov5640_set_ctrl_power_line_freq(dev, (int)(value)); + default: + return -ENOTSUP; + } +} + +static inline int ov5640_get_ctrl(const struct device *dev, unsigned int cid, void *value) +{ + struct ov5640_data *drv_data = dev->data; + + switch (cid) { + case VIDEO_CID_PIXEL_RATE: + *((uint64_t *)value) = drv_data->cur_pixrate; + + return 0; + default: + return -ENOTSUP; + } +} + +static int ov5640_get_frmival(const struct device *dev, enum video_endpoint_id ep, + struct video_frmival *frmival) +{ + struct ov5640_data *drv_data = dev->data; + + frmival->numerator = 1; + frmival->denominator = drv_data->cur_frmrate; + + return 0; +} + +static int ov5640_enum_frmival(const struct device *dev, enum video_endpoint_id ep, + struct video_frmival_enum *fie) +{ + uint8_t i = 0; + + for (i = 0; i < ARRAY_SIZE(modes); i++) { + if (fie->format->width == modes[i].width && + fie->format->height == modes[i].height) { + break; + } + } + + if (i == ARRAY_SIZE(modes) || fie->index > ARRAY_SIZE(ov5640_frame_rates) || + ov5640_frame_rates[fie->index] > modes[i].max_frmrate) { + return -EINVAL; + } + + fie->type = VIDEO_FRMIVAL_TYPE_DISCRETE; + fie->discrete.numerator = 1; + fie->discrete.denominator = ov5640_frame_rates[fie->index]; + + return 0; +} + static const struct video_driver_api ov5640_driver_api = { .set_format = ov5640_set_fmt, .get_format = ov5640_get_fmt, .get_caps = ov5640_get_caps, .stream_start = ov5640_stream_start, .stream_stop = ov5640_stream_stop, + .set_ctrl = ov5640_set_ctrl, + .get_ctrl = ov5640_get_ctrl, + .set_frmival = ov5640_set_frmival, + .get_frmival = ov5640_get_frmival, + .enum_frmival = ov5640_enum_frmival, }; static int ov5640_init(const struct device *dev) @@ -642,7 +989,7 @@ static int ov5640_init(const struct device *dev) k_sleep(K_MSEC(5)); /* Initialize register values */ - ret = ov5640_write_multi_regs(&cfg->i2c, ov5640InitParams, ARRAY_SIZE(ov5640InitParams)); + ret = ov5640_write_multi_regs(&cfg->i2c, init_params, ARRAY_SIZE(init_params)); if (ret) { LOG_ERR("Unable to initialize the sensor"); return -EIO; @@ -667,7 +1014,7 @@ static int ov5640_init(const struct device *dev) return -ENODEV; } - /* Set default format to 720p RGB565 */ + /* Set default format */ fmt.pixelformat = VIDEO_PIX_FMT_RGB565; fmt.width = 1280; fmt.height = 720; diff --git a/include/zephyr/drivers/video-controls.h b/include/zephyr/drivers/video-controls.h index 7912ab0d91cd2..e2c24802defea 100644 --- a/include/zephyr/drivers/video-controls.h +++ b/include/zephyr/drivers/video-controls.h @@ -33,11 +33,11 @@ extern "C" { * @name Control classes * @{ */ -#define VIDEO_CTRL_CLASS_GENERIC 0x00000000 /**< Generic class controls */ -#define VIDEO_CTRL_CLASS_CAMERA 0x00010000 /**< Camera class controls */ -#define VIDEO_CTRL_CLASS_MPEG 0x00020000 /**< MPEG-compression controls */ -#define VIDEO_CTRL_CLASS_JPEG 0x00030000 /**< JPEG-compression controls */ -#define VIDEO_CTRL_CLASS_VENDOR 0xFFFF0000 /**< Vendor-specific class controls */ +#define VIDEO_CTRL_CLASS_GENERIC 0x00000000 /**< Generic class controls */ +#define VIDEO_CTRL_CLASS_CAMERA 0x00010000 /**< Camera class controls */ +#define VIDEO_CTRL_CLASS_MPEG 0x00020000 /**< MPEG-compression controls */ +#define VIDEO_CTRL_CLASS_JPEG 0x00030000 /**< JPEG-compression controls */ +#define VIDEO_CTRL_CLASS_VENDOR 0xFFFF0000 /**< Vendor-specific class controls */ /** * @} */ @@ -47,9 +47,21 @@ extern "C" { * @{ */ /** Mirror the picture horizontally */ -#define VIDEO_CID_HFLIP (VIDEO_CTRL_CLASS_GENERIC + 0) +#define VIDEO_CID_HFLIP (VIDEO_CTRL_CLASS_GENERIC + 0) /** Mirror the picture vertically */ -#define VIDEO_CID_VFLIP (VIDEO_CTRL_CLASS_GENERIC + 1) +#define VIDEO_CID_VFLIP (VIDEO_CTRL_CLASS_GENERIC + 1) +/** Power line frequency (enum) filter to avoid flicker */ +#define VIDEO_CID_POWER_LINE_FREQUENCY (VIDEO_CTRL_CLASS_GENERIC + 2) +/** Pixel rate (pixels/second) in the device's pixel array. This control is read-only. */ +#define VIDEO_CID_PIXEL_RATE (VIDEO_CTRL_CLASS_GENERIC + 3) + +enum video_power_line_frequency { + VIDEO_CID_POWER_LINE_FREQUENCY_DISABLED = 0, + VIDEO_CID_POWER_LINE_FREQUENCY_50HZ = 1, + VIDEO_CID_POWER_LINE_FREQUENCY_60HZ = 2, + VIDEO_CID_POWER_LINE_FREQUENCY_AUTO = 3, +}; + /** * @} */ @@ -58,15 +70,16 @@ extern "C" { * @name Camera class control IDs * @{ */ -#define VIDEO_CID_CAMERA_EXPOSURE (VIDEO_CTRL_CLASS_CAMERA + 0) -#define VIDEO_CID_CAMERA_GAIN (VIDEO_CTRL_CLASS_CAMERA + 1) -#define VIDEO_CID_CAMERA_ZOOM (VIDEO_CTRL_CLASS_CAMERA + 2) -#define VIDEO_CID_CAMERA_BRIGHTNESS (VIDEO_CTRL_CLASS_CAMERA + 3) -#define VIDEO_CID_CAMERA_SATURATION (VIDEO_CTRL_CLASS_CAMERA + 4) -#define VIDEO_CID_CAMERA_WHITE_BAL (VIDEO_CTRL_CLASS_CAMERA + 5) -#define VIDEO_CID_CAMERA_CONTRAST (VIDEO_CTRL_CLASS_CAMERA + 6) -#define VIDEO_CID_CAMERA_COLORBAR (VIDEO_CTRL_CLASS_CAMERA + 7) -#define VIDEO_CID_CAMERA_QUALITY (VIDEO_CTRL_CLASS_CAMERA + 8) +#define VIDEO_CID_CAMERA_EXPOSURE (VIDEO_CTRL_CLASS_CAMERA + 0) +#define VIDEO_CID_CAMERA_GAIN (VIDEO_CTRL_CLASS_CAMERA + 1) +#define VIDEO_CID_CAMERA_ZOOM (VIDEO_CTRL_CLASS_CAMERA + 2) +#define VIDEO_CID_CAMERA_BRIGHTNESS (VIDEO_CTRL_CLASS_CAMERA + 3) +#define VIDEO_CID_CAMERA_SATURATION (VIDEO_CTRL_CLASS_CAMERA + 4) +#define VIDEO_CID_CAMERA_WHITE_BAL (VIDEO_CTRL_CLASS_CAMERA + 5) +#define VIDEO_CID_CAMERA_CONTRAST (VIDEO_CTRL_CLASS_CAMERA + 6) +#define VIDEO_CID_CAMERA_TEST_PATTERN (VIDEO_CTRL_CLASS_CAMERA + 7) +#define VIDEO_CID_CAMERA_QUALITY (VIDEO_CTRL_CLASS_CAMERA + 8) +#define VIDEO_CID_CAMERA_HUE (VIDEO_CTRL_CLASS_CAMERA + 9) /** * @} */ @@ -77,7 +90,6 @@ extern "C" { /* Controls */ - /** * @} */