Skip to content

Commit b0432a8

Browse files
Alain Volmatkartben
authored andcommitted
video: add LINK_FREQ ctrl and a helper to retrieve it
Add a ctrl VIDEO_CID_LINK_FREQ to indicate to a sink the frequency at which a device streams data over CSI2. Since not all source device currently provide the LINK_FREQ control, add a helper function to retrieve it, with a fall-back by doing an approximate via the PIXEL_RATE control. Signed-off-by: Alain Volmat <alain.volmat@foss.st.com>
1 parent b5d8aee commit b0432a8

File tree

4 files changed

+65
-0
lines changed

4 files changed

+65
-0
lines changed

drivers/video/video_common.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <zephyr/device.h>
1111
#include <zephyr/drivers/i2c.h>
1212
#include <zephyr/drivers/video.h>
13+
#include <zephyr/drivers/video-controls.h>
1314
#include <zephyr/kernel.h>
1415
#include <zephyr/logging/log.h>
1516
#include <zephyr/sys/byteorder.h>
@@ -390,3 +391,42 @@ int video_write_cci_multiregs16(const struct i2c_dt_spec *i2c, const struct vide
390391

391392
return 0;
392393
}
394+
395+
int64_t video_get_csi_link_freq(const struct device *dev, uint8_t bpp, uint8_t lane_nb)
396+
{
397+
struct video_control ctrl = {
398+
.id = VIDEO_CID_LINK_FREQ,
399+
};
400+
struct video_ctrl_query ctrl_query = {
401+
.id = VIDEO_CID_LINK_FREQ,
402+
};
403+
int ret;
404+
405+
/* Try to get the LINK_FREQ value from the source device */
406+
ret = video_get_ctrl(dev, &ctrl);
407+
if (ret < 0) {
408+
goto fallback;
409+
}
410+
411+
ret = video_query_ctrl(dev, &ctrl_query);
412+
if (ret < 0) {
413+
return ret;
414+
}
415+
416+
if (!IN_RANGE(ctrl.val, ctrl_query.range.min, ctrl_query.range.max)) {
417+
return -ERANGE;
418+
}
419+
420+
return (int64_t)ctrl_query.int_menu[ctrl.val];
421+
422+
fallback:
423+
/* If VIDEO_CID_LINK_FREQ is not available, approximate from VIDEO_CID_PIXEL_RATE */
424+
ctrl.id = VIDEO_CID_PIXEL_RATE;
425+
ret = video_get_ctrl(dev, &ctrl);
426+
if (ret < 0) {
427+
return ret;
428+
}
429+
430+
/* CSI D-PHY is using a DDR data bus so bitrate is twice the frequency */
431+
return ctrl.val64 * bpp / (2 * lane_nb);
432+
}

drivers/video/video_ctrls.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ static inline void set_type_flag(uint32_t id, enum video_ctrl_type *type, uint32
108108
*type = VIDEO_CTRL_TYPE_INTEGER64;
109109
*flags |= VIDEO_CTRL_FLAG_READ_ONLY;
110110
break;
111+
case VIDEO_CID_LINK_FREQ:
112+
*type = VIDEO_CTRL_TYPE_INTEGER_MENU;
113+
break;
111114
default:
112115
*type = VIDEO_CTRL_TYPE_INTEGER;
113116
break;
@@ -539,6 +542,8 @@ static inline const char *video_get_ctrl_name(uint32_t id)
539542
return "Pixel Rate";
540543
case VIDEO_CID_TEST_PATTERN:
541544
return "Test Pattern";
545+
case VIDEO_CID_LINK_FREQ:
546+
return "Link Frequency";
542547
default:
543548
return NULL;
544549
}

include/zephyr/drivers/video-controls.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,9 @@ enum video_camera_orientation {
362362
*/
363363
#define VIDEO_CID_IMAGE_PROC_CLASS_BASE 0x009f0900
364364

365+
/** Link frequency, applicable for the CSI2 based devices */
366+
#define VIDEO_CID_LINK_FREQ (VIDEO_CID_IMAGE_PROC_CLASS_BASE + 1)
367+
365368
/** Pixel rate (pixels/second) in the device's pixel array. This control is read-only. */
366369
#define VIDEO_CID_PIXEL_RATE (VIDEO_CID_IMAGE_PROC_CLASS_BASE + 2)
367370

include/zephyr/drivers/video.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,23 @@ void video_closest_frmival_stepwise(const struct video_frmival_stepwise *stepwis
842842
*/
843843
void video_closest_frmival(const struct device *dev, struct video_frmival_enum *match);
844844

845+
/**
846+
* @brief Return the link-frequency advertised by a device
847+
*
848+
* Device exposing a CSI link should advertise at least one of the following two controls:
849+
* - @ref VIDEO_CID_LINK_FREQ
850+
* - @ref VIDEO_CID_PIXEL_RATE
851+
*
852+
* At first the helper will try read the @ref VIDEO_CID_LINK_FREQ and if not available will
853+
* approximate the link-frequency from the @ref VIDEO_CID_PIXEL_RATE value, taking into
854+
* consideration the bits per pixel of the format and the number of lanes.
855+
*
856+
* @param dev Video device to query.
857+
* @param bpp Amount of bits per pixel of the pixel format produced by the device
858+
* @param lane_nb Number of CSI-2 lanes used
859+
*/
860+
int64_t video_get_csi_link_freq(const struct device *dev, uint8_t bpp, uint8_t lane_nb);
861+
845862
/**
846863
* @defgroup video_pixel_formats Video pixel formats
847864
* The '|' characters separate the pixels or logical blocks, and spaces separate the bytes.

0 commit comments

Comments
 (0)