From ec5aeb996b763842fdd171239d9ba43ea45cc857 Mon Sep 17 00:00:00 2001 From: Josuah Demangeon Date: Sun, 6 Oct 2024 17:12:43 +0000 Subject: [PATCH] drivers: video: common: add helpers to check video control range This allows implementing the VIDEO_CTRL_GET_MIN/MAX/DEF controls on drivers with minimum modification of the drivers. A typical usage in a video_get_ctrl() implementation would be: ret = video_get_ctrl_range(cid, value, 0, 320, 9); if (ret <= 0) { return ret; } return sensor_read_u32(&cfg->i2c, EXPOSURE_REG, value, 2); A typical usage in a video_set_ctrl() implementation would be: ret = video_check_range_u32(dev, cid, (uint32_t)value); if (ret < 0) { return ret; } return sensor_read_reg(&cfg->i2c, EXPOSURE_REG, value, 2); Signed-off-by: Josuah Demangeon --- drivers/video/video_common.c | 45 +++++++++++++++++++++++++++++++++++- drivers/video/video_common.h | 45 ++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 drivers/video/video_common.h diff --git a/drivers/video/video_common.c b/drivers/video/video_common.c index 6ff4c7b93385856..084f566088bb75a 100644 --- a/drivers/video/video_common.c +++ b/drivers/video/video_common.c @@ -3,10 +3,11 @@ * * SPDX-License-Identifier: Apache-2.0 */ - #include #include +#include "video_common.h" + #if defined(CONFIG_VIDEO_BUFFER_USE_SHARED_MULTI_HEAP) #include @@ -83,3 +84,45 @@ void video_buffer_release(struct video_buffer *vbuf) VIDEO_COMMON_FREE(block->data); } } + +int video_get_range_u32(unsigned int cid, uint32_t *value, uint32_t min, uint32_t max, uint32_t def) +{ + switch (cid & VIDEO_CTRL_GET_MASK) { + case VIDEO_CTRL_GET_MIN: + *value = min; + return 0; + case VIDEO_CTRL_GET_MAX: + *value = max; + return 0; + case VIDEO_CTRL_GET_DEF: + *value = def; + return 0; + case VIDEO_CTRL_GET_CUR: + return 1; + default: + return -ENOTSUP; + } +} + +int video_check_range_u32(const struct device *dev, unsigned int cid, uint32_t value) +{ + uint32_t min; + uint32_t max; + int ret; + + ret = video_get_ctrl(dev, cid | VIDEO_CTRL_GET_MIN, &min); + if (ret < 0) { + return ret; + } + + ret = video_get_ctrl(dev, cid | VIDEO_CTRL_GET_MAX, &max); + if (ret < 0) { + return ret; + } + + if (value < min || value > max) { + return -ERANGE; + } + + return 0; +} diff --git a/drivers/video/video_common.h b/drivers/video/video_common.h new file mode 100644 index 000000000000000..ce2ef13b1d8d5bc --- /dev/null +++ b/drivers/video/video_common.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024, tinyVision.ai Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_VIDEO_COMMON_H +#define ZEPHYR_INCLUDE_VIDEO_COMMON_H + +/** + * @brief Provide the minimum/maximum/default 32-bit value depending on the CID. + * + * Video CIDs can contain sub-operations. This function facilitates + * implementation of video controls in the drivers by handling these + * the range-related CIDs. + * + * @param cid The Video Control ID which contains the operation. + * @param min The minimum value returned if the CID requested it. + * @param max The maximum value returned if the CID requested it. + * @param def The default value returned if the CID requested it. + * + * @return 0 if the operation was regarding a range CID and the value could + * be set. In which case, there is nothing else to do than returning 0. + * @return 1 if the operation is not for the range, but the current value, + * in which case it is the duty of the driver to query the current + * value to the hardware + * @return A negative error code if an error occurred. + */ +int video_get_range_u32(unsigned int cid, uint32_t *u32, uint32_t min, uint32_t max, uint32_t def); + +/** + * @brief Check if the 32-bit value is within range for this CID. + * + * Before setting a video control, a driver might be interested in checking + * if it is within a valid range. This function facilitates it by reusing the + * video_get_ctrl() API using @c VIDEO_CTRL_GET_MIN and @c VIDEO_CTRL_GET_MAX + * to validate the input. + * + * @param dev The video device to query to learn about the min and max. + * @param cid The CID for which to check the range. + * @param u32 The 32-bit value that must be matched against the range. + */ +int video_check_range_u32(const struct device *dev, unsigned int cid, uint32_t u32); + +#endif /* ZEPHYR_INCLUDE_VIDEO_COMMON_H */