drivers: video: Support controls of 64-bit integer type
Add supports for controls that need 64-bit integer such as pixel rate. Signed-off-by: Phi Bang Nguyen <phibang.nguyen@nxp.com>
This commit is contained in:
parent
c95387a815
commit
f363bd6e36
14 changed files with 167 additions and 86 deletions
|
@ -1136,12 +1136,14 @@ static int gc2145_init_controls(const struct device *dev)
|
||||||
struct gc2145_data *drv_data = dev->data;
|
struct gc2145_data *drv_data = dev->data;
|
||||||
struct gc2145_ctrls *ctrls = &drv_data->ctrls;
|
struct gc2145_ctrls *ctrls = &drv_data->ctrls;
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->hflip, dev, VIDEO_CID_HFLIP, 0, 1, 1, 0);
|
ret = video_init_ctrl(&ctrls->hflip, dev, VIDEO_CID_HFLIP,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 0});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return video_init_ctrl(&ctrls->vflip, dev, VIDEO_CID_VFLIP, 0, 1, 1, 0);
|
return video_init_ctrl(&ctrls->vflip, dev, VIDEO_CID_VFLIP,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gc2145_init(const struct device *dev)
|
static int gc2145_init(const struct device *dev)
|
||||||
|
|
|
@ -514,13 +514,14 @@ static int mt9m114_init_controls(const struct device *dev)
|
||||||
struct mt9m114_data *drv_data = dev->data;
|
struct mt9m114_data *drv_data = dev->data;
|
||||||
struct mt9m114_ctrls *ctrls = &drv_data->ctrls;
|
struct mt9m114_ctrls *ctrls = &drv_data->ctrls;
|
||||||
|
|
||||||
|
ret = video_init_ctrl(&ctrls->hflip, dev, VIDEO_CID_HFLIP,
|
||||||
ret = video_init_ctrl(&ctrls->hflip, dev, VIDEO_CID_HFLIP, 0, 1, 1, 0);
|
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 0});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return video_init_ctrl(&ctrls->vflip, dev, VIDEO_CID_VFLIP, 0, 1, 1, 0);
|
return video_init_ctrl(&ctrls->vflip, dev, VIDEO_CID_VFLIP,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mt9m114_init(const struct device *dev)
|
static int mt9m114_init(const struct device *dev)
|
||||||
|
|
|
@ -940,52 +940,63 @@ static int ov2640_init_controls(const struct device *dev)
|
||||||
struct ov2640_data *drv_data = dev->data;
|
struct ov2640_data *drv_data = dev->data;
|
||||||
struct ov2640_ctrls *ctrls = &drv_data->ctrls;
|
struct ov2640_ctrls *ctrls = &drv_data->ctrls;
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->hflip, dev, VIDEO_CID_HFLIP, 0, 1, 1, 0);
|
ret = video_init_ctrl(&ctrls->hflip, dev, VIDEO_CID_HFLIP,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 0});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->vflip, dev, VIDEO_CID_VFLIP, 0, 1, 1, 0);
|
ret = video_init_ctrl(&ctrls->vflip, dev, VIDEO_CID_VFLIP,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 0});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->ae, dev, VIDEO_CID_EXPOSURE, 0, 1, 1, 1);
|
ret = video_init_ctrl(&ctrls->ae, dev, VIDEO_CID_EXPOSURE,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 1});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->awb, dev, VIDEO_CID_WHITE_BALANCE_TEMPERATURE, 0, 1, 1, 1);
|
ret = video_init_ctrl(&ctrls->awb, dev, VIDEO_CID_WHITE_BALANCE_TEMPERATURE,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 1});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->gain, dev, VIDEO_CID_GAIN, 0, 1, 1, 1);
|
ret = video_init_ctrl(&ctrls->gain, dev, VIDEO_CID_GAIN,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 1});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->brightness, dev, VIDEO_CID_BRIGHTNESS, -2, 2, 1, 0);
|
ret = video_init_ctrl(&ctrls->brightness, dev, VIDEO_CID_BRIGHTNESS,
|
||||||
|
(struct video_ctrl_range){.min = -2, .max = 2, .step = 1, .def = 0});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->contrast, dev, VIDEO_CID_CONTRAST, -2, 2, 1, 0);
|
ret = video_init_ctrl(&ctrls->contrast, dev, VIDEO_CID_CONTRAST,
|
||||||
|
(struct video_ctrl_range){.min = -2, .max = 2, .step = 1, .def = 0});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->saturation, dev, VIDEO_CID_SATURATION, -2, 2, 1, 0);
|
ret = video_init_ctrl(&ctrls->saturation, dev, VIDEO_CID_SATURATION,
|
||||||
|
(struct video_ctrl_range){.min = -2, .max = 2, .step = 1, .def = 0});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->jpeg, dev, VIDEO_CID_JPEG_COMPRESSION_QUALITY, 5, 100, 1, 50);
|
ret = video_init_ctrl(
|
||||||
|
&ctrls->jpeg, dev, VIDEO_CID_JPEG_COMPRESSION_QUALITY,
|
||||||
|
(struct video_ctrl_range){.min = 5, .max = 100, .step = 1, .def = 50});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return video_init_ctrl(&ctrls->test_pattern, dev, VIDEO_CID_TEST_PATTERN, 0, 1, 1, 0);
|
return video_init_ctrl(&ctrls->test_pattern, dev, VIDEO_CID_TEST_PATTERN,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ov2640_init(const struct device *dev)
|
static int ov2640_init(const struct device *dev)
|
||||||
|
|
|
@ -1182,59 +1182,77 @@ static int ov5640_init_controls(const struct device *dev)
|
||||||
struct ov5640_data *drv_data = dev->data;
|
struct ov5640_data *drv_data = dev->data;
|
||||||
struct ov5640_ctrls *ctrls = &drv_data->ctrls;
|
struct ov5640_ctrls *ctrls = &drv_data->ctrls;
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->gain, dev, VIDEO_CID_GAIN, 0, 1023, 1, 0);
|
ret = video_init_ctrl(
|
||||||
|
&ctrls->gain, dev, VIDEO_CID_GAIN,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 1023, .step = 1, .def = 0});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->brightness, dev, VIDEO_CID_BRIGHTNESS, -15, 15, 1, 0);
|
ret = video_init_ctrl(
|
||||||
|
&ctrls->brightness, dev, VIDEO_CID_BRIGHTNESS,
|
||||||
|
(struct video_ctrl_range){.min = -15, .max = 15, .step = 1, .def = 0});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->contrast, dev, VIDEO_CID_CONTRAST, 0, 255, 1, 0);
|
ret = video_init_ctrl(&ctrls->contrast, dev, VIDEO_CID_CONTRAST,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 255, .step = 1, .def = 0});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->hue, dev, VIDEO_CID_HUE, 0, 359, 1, 0);
|
ret = video_init_ctrl(&ctrls->hue, dev, VIDEO_CID_HUE,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 359, .step = 1, .def = 0});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->saturation, dev, VIDEO_CID_SATURATION, 0, 255, 1, 64);
|
ret = video_init_ctrl(
|
||||||
|
&ctrls->saturation, dev, VIDEO_CID_SATURATION,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 255, .step = 1, .def = 64});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->hflip, dev, VIDEO_CID_HFLIP, 0, 1, 1, 0);
|
ret = video_init_ctrl(&ctrls->hflip, dev, VIDEO_CID_HFLIP,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 0});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->vflip, dev, VIDEO_CID_VFLIP, 0, 1, 1, 0);
|
ret = video_init_ctrl(&ctrls->vflip, dev, VIDEO_CID_VFLIP,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 0});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->light_freq, dev, VIDEO_CID_POWER_LINE_FREQUENCY,
|
ret = video_init_ctrl(
|
||||||
VIDEO_CID_POWER_LINE_FREQUENCY_DISABLED,
|
&ctrls->light_freq, dev, VIDEO_CID_POWER_LINE_FREQUENCY,
|
||||||
VIDEO_CID_POWER_LINE_FREQUENCY_AUTO, 1,
|
(struct video_ctrl_range){.min = VIDEO_CID_POWER_LINE_FREQUENCY_DISABLED,
|
||||||
VIDEO_CID_POWER_LINE_FREQUENCY_50HZ);
|
.max = VIDEO_CID_POWER_LINE_FREQUENCY_AUTO,
|
||||||
|
.step = 1,
|
||||||
|
.def = VIDEO_CID_POWER_LINE_FREQUENCY_50HZ});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->test_pattern, dev, VIDEO_CID_TEST_PATTERN, 0,
|
ret = video_init_ctrl(
|
||||||
ARRAY_SIZE(test_pattern_val) - 1, 1, 0);
|
&ctrls->test_pattern, dev, VIDEO_CID_TEST_PATTERN,
|
||||||
|
(struct video_ctrl_range){
|
||||||
|
.min = 0, .max = ARRAY_SIZE(test_pattern_val) - 1, .step = 1, .def = 0});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return video_init_ctrl(
|
return video_init_ctrl(
|
||||||
&ctrls->pixel_rate, dev, VIDEO_CID_PIXEL_RATE, mipi_vga_frmrate_params[0].pixelrate,
|
&ctrls->pixel_rate, dev, VIDEO_CID_PIXEL_RATE,
|
||||||
mipi_hd_frmrate_params[ARRAY_SIZE(mipi_hd_frmrate_params) - 1].pixelrate, 1,
|
(struct video_ctrl_range){
|
||||||
drv_data->cur_pixrate);
|
.min64 = mipi_qqvga_frmrate_params[0].pixelrate,
|
||||||
|
.max64 = mipi_hd_frmrate_params[ARRAY_SIZE(mipi_hd_frmrate_params) - 1]
|
||||||
|
.pixelrate,
|
||||||
|
.step64 = 1,
|
||||||
|
.def64 = mipi_hd_frmrate_params[1].pixelrate});
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ov5640_init(const struct device *dev)
|
static int ov5640_init(const struct device *dev)
|
||||||
|
|
|
@ -464,12 +464,14 @@ static int ov7670_init_controls(const struct device *dev)
|
||||||
struct ov7670_data *drv_data = dev->data;
|
struct ov7670_data *drv_data = dev->data;
|
||||||
struct ov7670_ctrls *ctrls = &drv_data->ctrls;
|
struct ov7670_ctrls *ctrls = &drv_data->ctrls;
|
||||||
|
|
||||||
ret = video_init_ctrl(&ctrls->hflip, dev, VIDEO_CID_HFLIP, 0, 1, 1, 0);
|
ret = video_init_ctrl(&ctrls->hflip, dev, VIDEO_CID_HFLIP,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 0});
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return video_init_ctrl(&ctrls->vflip, dev, VIDEO_CID_VFLIP, 0, 1, 1, 0);
|
return video_init_ctrl(&ctrls->vflip, dev, VIDEO_CID_VFLIP,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ov7670_init(const struct device *dev)
|
static int ov7670_init(const struct device *dev)
|
||||||
|
|
|
@ -15,23 +15,29 @@
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(video_ctrls, CONFIG_VIDEO_LOG_LEVEL);
|
LOG_MODULE_REGISTER(video_ctrls, CONFIG_VIDEO_LOG_LEVEL);
|
||||||
|
|
||||||
static inline int check_range(enum video_ctrl_type type, int32_t min, int32_t max, uint32_t step,
|
static inline int check_range(enum video_ctrl_type type, struct video_ctrl_range range)
|
||||||
int32_t def)
|
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case VIDEO_CTRL_TYPE_BOOLEAN:
|
case VIDEO_CTRL_TYPE_BOOLEAN:
|
||||||
if (step != 1 || max > 1 || min < 0) {
|
if (range.step != 1 || range.max > 1 || range.min < 0) {
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
case VIDEO_CTRL_TYPE_INTEGER:
|
case VIDEO_CTRL_TYPE_INTEGER:
|
||||||
|
if (range.step == 0 || range.min > range.max ||
|
||||||
|
!IN_RANGE(range.def, range.min, range.max)) {
|
||||||
|
return -ERANGE;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
case VIDEO_CTRL_TYPE_INTEGER64:
|
case VIDEO_CTRL_TYPE_INTEGER64:
|
||||||
if (step == 0 || min > max || !IN_RANGE(def, min, max)) {
|
if (range.step64 == 0 || range.min64 > range.max64 ||
|
||||||
|
!IN_RANGE(range.def64, range.min64, range.max64)) {
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
case VIDEO_CTRL_TYPE_MENU:
|
case VIDEO_CTRL_TYPE_MENU:
|
||||||
if (!IN_RANGE(min, 0, max) || !IN_RANGE(def, min, max)) {
|
if (!IN_RANGE(range.min, 0, range.max) ||
|
||||||
|
!IN_RANGE(range.def, range.min, range.max)) {
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -63,8 +69,8 @@ static inline void set_type_flag(uint32_t id, enum video_ctrl_type *type, uint32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int video_init_ctrl(struct video_ctrl *ctrl, const struct device *dev, uint32_t id, int32_t min,
|
int video_init_ctrl(struct video_ctrl *ctrl, const struct device *dev, uint32_t id,
|
||||||
int32_t max, uint32_t step, int32_t def)
|
struct video_ctrl_range range)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
@ -83,7 +89,7 @@ int video_init_ctrl(struct video_ctrl *ctrl, const struct device *dev, uint32_t
|
||||||
|
|
||||||
set_type_flag(id, &type, &flags);
|
set_type_flag(id, &type, &flags);
|
||||||
|
|
||||||
ret = check_range(type, min, max, step, def);
|
ret = check_range(type, range);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -92,11 +98,13 @@ int video_init_ctrl(struct video_ctrl *ctrl, const struct device *dev, uint32_t
|
||||||
ctrl->id = id;
|
ctrl->id = id;
|
||||||
ctrl->type = type;
|
ctrl->type = type;
|
||||||
ctrl->flags = flags;
|
ctrl->flags = flags;
|
||||||
ctrl->min = min;
|
ctrl->range = range;
|
||||||
ctrl->max = max;
|
|
||||||
ctrl->step = step;
|
if (type == VIDEO_CTRL_TYPE_INTEGER64) {
|
||||||
ctrl->def = def;
|
ctrl->val64 = range.def64;
|
||||||
ctrl->val = def;
|
} else {
|
||||||
|
ctrl->val = range.def;
|
||||||
|
}
|
||||||
|
|
||||||
/* Insert in an ascending order of ctrl's id */
|
/* Insert in an ascending order of ctrl's id */
|
||||||
SYS_DLIST_FOR_EACH_CONTAINER(&vdev->ctrls, vc, node) {
|
SYS_DLIST_FOR_EACH_CONTAINER(&vdev->ctrls, vc, node) {
|
||||||
|
@ -143,7 +151,11 @@ int video_get_ctrl(const struct device *dev, struct video_control *control)
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
control->val = ctrl->val;
|
if (ctrl->type == VIDEO_CTRL_TYPE_INTEGER64) {
|
||||||
|
control->val64 = ctrl->val64;
|
||||||
|
} else {
|
||||||
|
control->val = ctrl->val;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -163,7 +175,9 @@ int video_set_ctrl(const struct device *dev, struct video_control *control)
|
||||||
return -EACCES;
|
return -EACCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IN_RANGE(control->val, ctrl->min, ctrl->max)) {
|
if (ctrl->type == VIDEO_CTRL_TYPE_INTEGER64
|
||||||
|
? !IN_RANGE(control->val64, ctrl->range.min64, ctrl->range.max64)
|
||||||
|
: !IN_RANGE(control->val, ctrl->range.min, ctrl->range.max)) {
|
||||||
LOG_ERR("Control value is invalid\n");
|
LOG_ERR("Control value is invalid\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -180,7 +194,11 @@ int video_set_ctrl(const struct device *dev, struct video_control *control)
|
||||||
|
|
||||||
update:
|
update:
|
||||||
/* Only update the ctrl in memory once everything is OK */
|
/* Only update the ctrl in memory once everything is OK */
|
||||||
ctrl->val = control->val;
|
if (ctrl->type == VIDEO_CTRL_TYPE_INTEGER64) {
|
||||||
|
ctrl->val64 = control->val64;
|
||||||
|
} else {
|
||||||
|
ctrl->val = control->val;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -255,10 +273,8 @@ fill_query:
|
||||||
cq->id = ctrl->id;
|
cq->id = ctrl->id;
|
||||||
cq->type = ctrl->type;
|
cq->type = ctrl->type;
|
||||||
cq->flags = ctrl->flags;
|
cq->flags = ctrl->flags;
|
||||||
cq->min = ctrl->min;
|
cq->range = ctrl->range;
|
||||||
cq->max = ctrl->max;
|
|
||||||
cq->step = ctrl->step;
|
|
||||||
cq->def = ctrl->def;
|
|
||||||
cq->name = video_get_ctrl_name(cq->id);
|
cq->name = video_get_ctrl_name(cq->id);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -43,12 +43,15 @@ struct video_ctrl {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
enum video_ctrl_type type;
|
enum video_ctrl_type type;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int32_t min, max, def, val;
|
struct video_ctrl_range range;
|
||||||
uint32_t step;
|
union {
|
||||||
|
int32_t val;
|
||||||
|
int64_t val64;
|
||||||
|
};
|
||||||
sys_dnode_t node;
|
sys_dnode_t node;
|
||||||
};
|
};
|
||||||
|
|
||||||
int video_init_ctrl(struct video_ctrl *ctrl, const struct device *dev, uint32_t id, int32_t min,
|
int video_init_ctrl(struct video_ctrl *ctrl, const struct device *dev, uint32_t id,
|
||||||
int32_t max, uint32_t step, int32_t def);
|
struct video_ctrl_range range);
|
||||||
|
|
||||||
#endif /* ZEPHYR_INCLUDE_DRIVERS_VIDEO_VIDEO_CTRLS_H_ */
|
#endif /* ZEPHYR_INCLUDE_DRIVERS_VIDEO_VIDEO_CTRLS_H_ */
|
||||||
|
|
|
@ -366,8 +366,9 @@ static int emul_imager_init_controls(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct emul_imager_data *drv_data = dev->data;
|
struct emul_imager_data *drv_data = dev->data;
|
||||||
|
|
||||||
return video_init_ctrl(&drv_data->ctrls.custom, dev, EMUL_IMAGER_CID_CUSTOM, 0, 255, 1,
|
return video_init_ctrl(
|
||||||
128);
|
&drv_data->ctrls.custom, dev, EMUL_IMAGER_CID_CUSTOM,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 255, .step = 1, .def = 128});
|
||||||
}
|
}
|
||||||
|
|
||||||
int emul_imager_init(const struct device *dev)
|
int emul_imager_init(const struct device *dev)
|
||||||
|
|
|
@ -56,7 +56,7 @@ static int mipi_csi2rx_update_settings(const struct device *dev, enum video_endp
|
||||||
uint32_t root_clk_rate, ui_clk_rate, sensor_byte_clk, best_match;
|
uint32_t root_clk_rate, ui_clk_rate, sensor_byte_clk, best_match;
|
||||||
int ret, ind = 0;
|
int ret, ind = 0;
|
||||||
struct video_format fmt;
|
struct video_format fmt;
|
||||||
struct video_control sensor_rate = {VIDEO_CID_PIXEL_RATE, -1};
|
struct video_control sensor_rate = {.id = VIDEO_CID_PIXEL_RATE, .val64 = -1};
|
||||||
|
|
||||||
ret = video_get_format(config->sensor_dev, ep, &fmt);
|
ret = video_get_format(config->sensor_dev, ep, &fmt);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -65,13 +65,13 @@ static int mipi_csi2rx_update_settings(const struct device *dev, enum video_endp
|
||||||
}
|
}
|
||||||
|
|
||||||
video_get_ctrl(config->sensor_dev, &sensor_rate);
|
video_get_ctrl(config->sensor_dev, &sensor_rate);
|
||||||
if (!IN_RANGE(sensor_rate.val, 0, MAX_SUPPORTED_PIXEL_RATE)) {
|
if (!IN_RANGE(sensor_rate.val64, 0, MAX_SUPPORTED_PIXEL_RATE)) {
|
||||||
LOG_ERR("Sensor pixel rate is not supported");
|
LOG_ERR("Sensor pixel rate is not supported %lld", sensor_rate.val64);
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
bpp = video_bits_per_pixel(fmt.pixelformat);
|
bpp = video_bits_per_pixel(fmt.pixelformat);
|
||||||
sensor_byte_clk = sensor_rate.val * bpp / drv_data->csi2rxConfig.laneNum / BITS_PER_BYTE;
|
sensor_byte_clk = sensor_rate.val64 * bpp / drv_data->csi2rxConfig.laneNum / BITS_PER_BYTE;
|
||||||
|
|
||||||
ret = clock_control_get_rate(drv_data->clock_dev, drv_data->clock_root, &root_clk_rate);
|
ret = clock_control_get_rate(drv_data->clock_dev, drv_data->clock_root, &root_clk_rate);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -91,10 +91,10 @@ static int mipi_csi2rx_update_settings(const struct device *dev, enum video_endp
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sensor_rate.val > ui_clk_rate) {
|
if (sensor_rate.val64 > ui_clk_rate) {
|
||||||
ret = clock_control_set_rate(
|
ret = clock_control_set_rate(
|
||||||
drv_data->clock_dev, drv_data->clock_ui,
|
drv_data->clock_dev, drv_data->clock_ui,
|
||||||
(clock_control_subsys_rate_t)(uint32_t)sensor_rate.val);
|
(clock_control_subsys_rate_t)(uint32_t)sensor_rate.val64);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ static int mipi_csi2rx_update_settings(const struct device *dev, enum video_endp
|
||||||
/* Find the supported sensor_pixel_rate closest to the desired one */
|
/* Find the supported sensor_pixel_rate closest to the desired one */
|
||||||
best_match = tHsSettleEscClk_configs[ind].pixel_rate;
|
best_match = tHsSettleEscClk_configs[ind].pixel_rate;
|
||||||
for (uint8_t i = 0; i < ARRAY_SIZE(tHsSettleEscClk_configs); i++) {
|
for (uint8_t i = 0; i < ARRAY_SIZE(tHsSettleEscClk_configs); i++) {
|
||||||
if (ABS(tHsSettleEscClk_configs[i].pixel_rate, sensor_rate.val) <
|
if (ABS(tHsSettleEscClk_configs[i].pixel_rate, sensor_rate.val64) <
|
||||||
ABS(tHsSettleEscClk_configs[i].pixel_rate, best_match)) {
|
ABS(tHsSettleEscClk_configs[i].pixel_rate, best_match)) {
|
||||||
best_match = tHsSettleEscClk_configs[i].pixel_rate;
|
best_match = tHsSettleEscClk_configs[i].pixel_rate;
|
||||||
ind = i;
|
ind = i;
|
||||||
|
@ -228,7 +228,7 @@ static int mipi_csi2rx_enum_frmival(const struct device *dev, enum video_endpoin
|
||||||
uint64_t est_pixel_rate;
|
uint64_t est_pixel_rate;
|
||||||
struct video_frmival cur_frmival;
|
struct video_frmival cur_frmival;
|
||||||
struct video_format cur_fmt;
|
struct video_format cur_fmt;
|
||||||
struct video_control sensor_rate = {VIDEO_CID_PIXEL_RATE, -1};
|
struct video_control sensor_rate = {.id = VIDEO_CID_PIXEL_RATE, .val64 = -1};
|
||||||
|
|
||||||
ret = video_enum_frmival(config->sensor_dev, ep, fie);
|
ret = video_enum_frmival(config->sensor_dev, ep, fie);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -254,7 +254,7 @@ static int mipi_csi2rx_enum_frmival(const struct device *dev, enum video_endpoin
|
||||||
|
|
||||||
if (fie->type == VIDEO_FRMIVAL_TYPE_DISCRETE) {
|
if (fie->type == VIDEO_FRMIVAL_TYPE_DISCRETE) {
|
||||||
est_pixel_rate = mipi_csi2rx_estimate_pixel_rate(
|
est_pixel_rate = mipi_csi2rx_estimate_pixel_rate(
|
||||||
&cur_frmival, &fie->discrete, &cur_fmt, fie->format, sensor_rate.val,
|
&cur_frmival, &fie->discrete, &cur_fmt, fie->format, sensor_rate.val64,
|
||||||
drv_data->csi2rxConfig.laneNum);
|
drv_data->csi2rxConfig.laneNum);
|
||||||
if (est_pixel_rate > MAX_SUPPORTED_PIXEL_RATE) {
|
if (est_pixel_rate > MAX_SUPPORTED_PIXEL_RATE) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -263,7 +263,7 @@ static int mipi_csi2rx_enum_frmival(const struct device *dev, enum video_endpoin
|
||||||
} else {
|
} else {
|
||||||
/* Check the lane rate of the lower bound framerate */
|
/* Check the lane rate of the lower bound framerate */
|
||||||
est_pixel_rate = mipi_csi2rx_estimate_pixel_rate(
|
est_pixel_rate = mipi_csi2rx_estimate_pixel_rate(
|
||||||
&cur_frmival, &fie->stepwise.min, &cur_fmt, fie->format, sensor_rate.val,
|
&cur_frmival, &fie->stepwise.min, &cur_fmt, fie->format, sensor_rate.val64,
|
||||||
drv_data->csi2rxConfig.laneNum);
|
drv_data->csi2rxConfig.laneNum);
|
||||||
if (est_pixel_rate > MAX_SUPPORTED_PIXEL_RATE) {
|
if (est_pixel_rate > MAX_SUPPORTED_PIXEL_RATE) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -271,13 +271,13 @@ static int mipi_csi2rx_enum_frmival(const struct device *dev, enum video_endpoin
|
||||||
|
|
||||||
/* Check the lane rate of the upper bound framerate */
|
/* Check the lane rate of the upper bound framerate */
|
||||||
est_pixel_rate = mipi_csi2rx_estimate_pixel_rate(
|
est_pixel_rate = mipi_csi2rx_estimate_pixel_rate(
|
||||||
&cur_frmival, &fie->stepwise.max, &cur_fmt, fie->format, sensor_rate.val,
|
&cur_frmival, &fie->stepwise.max, &cur_fmt, fie->format, sensor_rate.val64,
|
||||||
drv_data->csi2rxConfig.laneNum);
|
drv_data->csi2rxConfig.laneNum);
|
||||||
if (est_pixel_rate > MAX_SUPPORTED_PIXEL_RATE) {
|
if (est_pixel_rate > MAX_SUPPORTED_PIXEL_RATE) {
|
||||||
fie->stepwise.max.denominator =
|
fie->stepwise.max.denominator =
|
||||||
(mipi_csi2rx_cal_frame_size(&cur_fmt) * MAX_SUPPORTED_PIXEL_RATE *
|
(mipi_csi2rx_cal_frame_size(&cur_fmt) * MAX_SUPPORTED_PIXEL_RATE *
|
||||||
cur_frmival.denominator) /
|
cur_frmival.denominator) /
|
||||||
(mipi_csi2rx_cal_frame_size(fie->format) * sensor_rate.val *
|
(mipi_csi2rx_cal_frame_size(fie->format) * sensor_rate.val64 *
|
||||||
cur_frmival.numerator);
|
cur_frmival.numerator);
|
||||||
fie->stepwise.max.numerator = 1;
|
fie->stepwise.max.numerator = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -350,7 +350,8 @@ static int video_sw_generator_init_controls(const struct device *dev)
|
||||||
{
|
{
|
||||||
struct video_sw_generator_data *data = dev->data;
|
struct video_sw_generator_data *data = dev->data;
|
||||||
|
|
||||||
return video_init_ctrl(&data->ctrls.hflip, dev, VIDEO_CID_HFLIP, 0, 1, 1, 0);
|
return video_init_ctrl(&data->ctrls.hflip, dev, VIDEO_CID_HFLIP,
|
||||||
|
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
static int video_sw_generator_init(const struct device *dev)
|
static int video_sw_generator_init(const struct device *dev)
|
||||||
|
|
|
@ -193,7 +193,41 @@ struct video_control {
|
||||||
/** control id */
|
/** control id */
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
/** control value */
|
/** control value */
|
||||||
int32_t val;
|
union {
|
||||||
|
int32_t val;
|
||||||
|
int64_t val64;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct video_control_range
|
||||||
|
* @brief Video control range structure
|
||||||
|
*
|
||||||
|
* Describe range of a control including min, max, step and default values
|
||||||
|
*/
|
||||||
|
struct video_ctrl_range {
|
||||||
|
/** control minimum value, inclusive */
|
||||||
|
union {
|
||||||
|
int32_t min;
|
||||||
|
int64_t min64;
|
||||||
|
};
|
||||||
|
/** control maximum value, inclusive */
|
||||||
|
union {
|
||||||
|
int32_t max;
|
||||||
|
int64_t max64;
|
||||||
|
};
|
||||||
|
/** control value step */
|
||||||
|
union {
|
||||||
|
int32_t step;
|
||||||
|
int64_t step64;
|
||||||
|
};
|
||||||
|
/** control default value for VIDEO_CTRL_TYPE_INTEGER, _BOOLEAN, _MENU or
|
||||||
|
* _INTEGER_MENU, not valid for other types
|
||||||
|
*/
|
||||||
|
union {
|
||||||
|
int32_t def;
|
||||||
|
int64_t def64;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -211,16 +245,8 @@ struct video_ctrl_query {
|
||||||
const char *name;
|
const char *name;
|
||||||
/** control flags */
|
/** control flags */
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
/** control minimum value, inclusive */
|
/** control range */
|
||||||
int32_t min;
|
struct video_ctrl_range range;
|
||||||
/** control maximum value, inclusive */
|
|
||||||
int32_t max;
|
|
||||||
/** control value step */
|
|
||||||
int32_t step;
|
|
||||||
/** control default value for VIDEO_CTRL_TYPE_INTEGER, _BOOLEAN, _MENU or
|
|
||||||
* _INTEGER_MENU, not valid for other types
|
|
||||||
*/
|
|
||||||
int32_t def;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -186,7 +186,7 @@ int main(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set controls */
|
/* Set controls */
|
||||||
struct video_control ctrl = {VIDEO_CID_HFLIP, 1};
|
struct video_control ctrl = {.id = VIDEO_CID_HFLIP, .val = 1};
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_VIDEO_CTRL_HFLIP)) {
|
if (IS_ENABLED(CONFIG_VIDEO_CTRL_HFLIP)) {
|
||||||
video_set_ctrl(video_dev, &ctrl);
|
video_set_ctrl(video_dev, &ctrl);
|
||||||
|
|
|
@ -107,7 +107,7 @@ int main(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set controls */
|
/* Set controls */
|
||||||
struct video_control ctrl = {VIDEO_CID_HFLIP, 1};
|
struct video_control ctrl = {.id = VIDEO_CID_HFLIP, .val = 1};
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_VIDEO_HFLIP)) {
|
if (IS_ENABLED(CONFIG_VIDEO_HFLIP)) {
|
||||||
video_set_ctrl(video_dev, &ctrl);
|
video_set_ctrl(video_dev, &ctrl);
|
||||||
|
|
|
@ -127,7 +127,7 @@ ZTEST(video_common, test_video_frmival)
|
||||||
|
|
||||||
ZTEST(video_common, test_video_ctrl)
|
ZTEST(video_common, test_video_ctrl)
|
||||||
{
|
{
|
||||||
struct video_control ctrl = {VIDEO_CID_PRIVATE_BASE + 0x01, 30};
|
struct video_control ctrl = {.id = VIDEO_CID_PRIVATE_BASE + 0x01, .val = 30};
|
||||||
|
|
||||||
/* Emulated vendor specific control, expected to be supported by all imagers */
|
/* Emulated vendor specific control, expected to be supported by all imagers */
|
||||||
zexpect_ok(video_set_ctrl(imager_dev, &ctrl));
|
zexpect_ok(video_set_ctrl(imager_dev, &ctrl));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue