diff --git a/drivers/video/video_ctrls.c b/drivers/video/video_ctrls.c index cb2ec49b575..b3176c943d6 100644 --- a/drivers/video/video_ctrls.c +++ b/drivers/video/video_ctrls.c @@ -70,6 +70,7 @@ static inline int check_range(enum video_ctrl_type type, struct video_ctrl_range } return 0; case VIDEO_CTRL_TYPE_MENU: + case VIDEO_CTRL_TYPE_INTEGER_MENU: if (!IN_RANGE(range.min, 0, range.max) || !IN_RANGE(range.def, range.min, range.max)) { return -ERANGE; @@ -200,6 +201,28 @@ int video_init_menu_ctrl(struct video_ctrl *ctrl, const struct device *dev, uint return 0; } +int video_init_int_menu_ctrl(struct video_ctrl *ctrl, const struct device *dev, uint32_t id, + uint8_t def, const int64_t menu[], size_t menu_len) +{ + int ret; + + if (!menu) { + return -EINVAL; + } + + ret = video_init_ctrl( + ctrl, dev, id, + (struct video_ctrl_range){.min = 0, .max = menu_len - 1, .step = 1, .def = def}); + + if (ret) { + return ret; + } + + ctrl->int_menu = menu; + + return 0; +} + /* By definition, the cluster is in manual mode if the master control value is 0 */ static inline bool is_cluster_manual(const struct video_ctrl *master) { @@ -554,7 +577,11 @@ fill_query: cq->type = ctrl->type; cq->flags = ctrl->flags; cq->range = ctrl->range; - cq->menu = ctrl->menu; + if (cq->type == VIDEO_CTRL_TYPE_MENU) { + cq->menu = ctrl->menu; + } else if (cq->type == VIDEO_CTRL_TYPE_INTEGER_MENU) { + cq->int_menu = ctrl->int_menu; + } cq->name = video_get_ctrl_name(cq->id); return 0; @@ -583,6 +610,9 @@ void video_print_ctrl(const struct device *const dev, const struct video_ctrl_qu case VIDEO_CTRL_TYPE_MENU: type = "menu"; break; + case VIDEO_CTRL_TYPE_INTEGER_MENU: + type = "integer menu"; + break; case VIDEO_CTRL_TYPE_STRING: type = "string"; break; @@ -609,10 +639,15 @@ void video_print_ctrl(const struct device *const dev, const struct video_ctrl_qu cq->range.step, cq->range.def, vc.val); } - if (cq->menu) { + if (cq->type == VIDEO_CTRL_TYPE_MENU && cq->menu) { while (cq->menu[i]) { LOG_INF("%*s %u: %s", 32, "", i, cq->menu[i]); i++; } + } else if (cq->type == VIDEO_CTRL_TYPE_INTEGER_MENU && cq->int_menu) { + while (cq->int_menu[i]) { + LOG_INF("%*s %u: %lld", 12, "", i, cq->int_menu[i]); + i++; + } } } diff --git a/drivers/video/video_ctrls.h b/drivers/video/video_ctrls.h index 07c6c5575f3..485eacc4a3c 100644 --- a/drivers/video/video_ctrls.h +++ b/drivers/video/video_ctrls.h @@ -27,10 +27,12 @@ enum video_ctrl_type { VIDEO_CTRL_TYPE_INTEGER = 2, /** 64-bit integer type */ VIDEO_CTRL_TYPE_INTEGER64 = 3, - /** Menu type, standard or driver-defined menu */ + /** Menu string type, standard or driver-defined menu */ VIDEO_CTRL_TYPE_MENU = 4, /** String type */ VIDEO_CTRL_TYPE_STRING = 5, + /** Menu integer type, standard or driver-defined menu */ + VIDEO_CTRL_TYPE_INTEGER_MENU = 6, }; struct video_device; @@ -54,7 +56,10 @@ struct video_ctrl { int32_t val; int64_t val64; }; - const char *const *menu; + union { + const char *const *menu; + const int64_t *int_menu; + }; sys_dnode_t node; }; @@ -64,6 +69,9 @@ int video_init_ctrl(struct video_ctrl *ctrl, const struct device *dev, uint32_t int video_init_menu_ctrl(struct video_ctrl *ctrl, const struct device *dev, uint32_t id, uint8_t def, const char *const menu[]); +int video_init_int_menu_ctrl(struct video_ctrl *ctrl, const struct device *dev, uint32_t id, + uint8_t def, const int64_t menu[], size_t menu_len); + void video_cluster_ctrl(struct video_ctrl *ctrls, uint8_t sz); void video_auto_cluster_ctrl(struct video_ctrl *ctrls, uint8_t sz, bool set_volatile); diff --git a/include/zephyr/drivers/video-controls.h b/include/zephyr/drivers/video-controls.h index 79141eb430d..5ffe4a507ed 100644 --- a/include/zephyr/drivers/video-controls.h +++ b/include/zephyr/drivers/video-controls.h @@ -463,7 +463,10 @@ struct video_ctrl_query { /** control range */ struct video_ctrl_range range; /** menu if control is of menu type */ - const char *const *menu; + union { + const char *const *menu; + const int64_t *int_menu; + }; }; /**