Skip to content

Commit 3bd46c6

Browse files
committed
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 <me@josuah.net>
1 parent 99a871e commit 3bd46c6

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed

drivers/video/video_common.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
#include <zephyr/kernel.h>
88
#include <zephyr/drivers/video.h>
9+
#include <zephyr/drivers/video-controls.h>
10+
11+
#include "video_common.h"
912

1013
#if defined(CONFIG_VIDEO_BUFFER_USE_SHARED_MULTI_HEAP)
1114
#include <zephyr/multi_heap/shared_multi_heap.h>
@@ -83,3 +86,87 @@ void video_buffer_release(struct video_buffer *vbuf)
8386
VIDEO_COMMON_FREE(block->data);
8487
}
8588
}
89+
90+
int video_get_range_int(unsigned int cid, int *value, int min, int max, int def)
91+
{
92+
switch (cid & VIDEO_CTRL_GET_MASK) {
93+
case VIDEO_CTRL_GET_MIN:
94+
*value = min;
95+
return 0;
96+
case VIDEO_CTRL_GET_MAX:
97+
*value = max;
98+
return 0;
99+
case VIDEO_CTRL_GET_DEF:
100+
*value = def;
101+
return 0;
102+
case VIDEO_CTRL_GET_CUR:
103+
return 1;
104+
default:
105+
return -ENOTSUP;
106+
}
107+
}
108+
109+
int video_get_range_int64(unsigned int cid, int64_t *value, int64_t min, int64_t max, int64_t def)
110+
{
111+
switch (cid & VIDEO_CTRL_GET_MASK) {
112+
case VIDEO_CTRL_GET_MIN:
113+
*value = min;
114+
return 0;
115+
case VIDEO_CTRL_GET_MAX:
116+
*value = max;
117+
return 0;
118+
case VIDEO_CTRL_GET_DEF:
119+
*value = def;
120+
return 0;
121+
case VIDEO_CTRL_GET_CUR:
122+
return 1;
123+
default:
124+
return -ENOTSUP;
125+
}
126+
}
127+
128+
int video_check_range_int(const struct device *dev, unsigned int cid, int value)
129+
{
130+
int min;
131+
int max;
132+
int ret;
133+
134+
ret = video_get_ctrl(dev, cid | VIDEO_CTRL_GET_MIN, &min);
135+
if (ret < 0) {
136+
return ret;
137+
}
138+
139+
ret = video_get_ctrl(dev, cid | VIDEO_CTRL_GET_MAX, &max);
140+
if (ret < 0) {
141+
return ret;
142+
}
143+
144+
if (value < min || value > max || min > max) {
145+
return -ERANGE;
146+
}
147+
148+
return 0;
149+
}
150+
151+
int video_check_range_int64(const struct device *dev, unsigned int cid, int64_t value)
152+
{
153+
int64_t min;
154+
int64_t max;
155+
int ret;
156+
157+
ret = video_get_ctrl(dev, cid | VIDEO_CTRL_GET_MIN, &min);
158+
if (ret < 0) {
159+
return ret;
160+
}
161+
162+
ret = video_get_ctrl(dev, cid | VIDEO_CTRL_GET_MAX, &max);
163+
if (ret < 0) {
164+
return ret;
165+
}
166+
167+
if (value < min || value > max || min > max) {
168+
return -ERANGE;
169+
}
170+
171+
return 0;
172+
}

drivers/video/video_common.h

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright (c) 2024, tinyVision.ai Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef ZEPHYR_INCLUDE_VIDEO_COMMON_H
8+
#define ZEPHYR_INCLUDE_VIDEO_COMMON_H
9+
10+
/**
11+
* @brief Provide the minimum/maximum/default integer value depending on the CID.
12+
*
13+
* Video CIDs can contain sub-operations. This function facilitates
14+
* implementation of video controls in the drivers by handling these
15+
* the range-related CIDs.
16+
*
17+
* @param cid The Video Control ID which contains the operation.
18+
* @param value The value, selected among @p min, @p max and @p def.
19+
* @param min The minimum value returned if the CID requested it.
20+
* @param max The maximum value returned if the CID requested it.
21+
* @param def The default value returned if the CID requested it.
22+
*
23+
* @return 0 if the operation was regarding a range CID and the value could
24+
* be set. In which case, there is nothing else to do than returning 0.
25+
* @return 1 if the operation is not for the range, but the current value,
26+
* in which case it is the duty of the driver to query the current
27+
* value to the hardware
28+
* @return A negative error code if an error occurred.
29+
*
30+
* @{
31+
*/
32+
33+
/** Signed integer version */
34+
int video_get_range_int(unsigned int cid, int *value, int min, int max, int def);
35+
36+
/** Signed 64-bit version */
37+
int video_get_range_int64(unsigned int cid, int64_t *value, int64_t min, int64_t max, int64_t def);
38+
39+
/**
40+
* @}
41+
*/
42+
43+
/**
44+
* @brief Check if the integer value is within range for this CID.
45+
*
46+
* Before setting a video control, a driver might be interested in checking
47+
* if it is within a valid range. This function facilitates it by reusing the
48+
* video_get_ctrl() API using @c VIDEO_CTRL_GET_MIN and @c VIDEO_CTRL_GET_MAX
49+
* to validate the input.
50+
*
51+
* @param dev The video device to query to learn about the min and max.
52+
* @param cid The CID for which to check the range.
53+
* @param value The integer value that must be matched against the range.
54+
*
55+
* @{
56+
*/
57+
58+
/** Signed integer version */
59+
int video_check_range_int(const struct device *dev, unsigned int cid, int value);
60+
61+
/** Signed 64-bit version */
62+
int video_check_range_int64(const struct device *dev, unsigned int cid, int64_t value);
63+
64+
/**
65+
* @}
66+
*/
67+
68+
#endif /* ZEPHYR_INCLUDE_VIDEO_COMMON_H */

0 commit comments

Comments
 (0)