Skip to content

Commit be136f8

Browse files
author
Alain Volmat
committed
video: add LINK_FREQUENCY ctrl and a helper to retrieve it
Add a read-only ctrl VIDEO_CID_LINK_FREQUENCY to indicate to a sink the frequency at which a device streams data over CSI2. Since not all source device currently provide the LINK_FREQUENCY 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 e306902 commit be136f8

File tree

4 files changed

+66
-0
lines changed

4 files changed

+66
-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>
@@ -365,3 +366,42 @@ int video_write_cci_multiregs16(const struct i2c_dt_spec *i2c, const struct vide
365366

366367
return 0;
367368
}
369+
370+
int64_t video_get_link_frequency(const struct device *dev, uint8_t bpp, uint8_t lane_nb)
371+
{
372+
int ret;
373+
374+
struct video_control ctrl = {
375+
.id = VIDEO_CID_LINK_FREQUENCY,
376+
};
377+
struct video_ctrl_query ctrl_query = {
378+
.id = VIDEO_CID_LINK_FREQUENCY,
379+
};
380+
381+
/* Try to get the LINK_FREQUENCY value from the source device */
382+
ret = video_get_ctrl(dev, &ctrl);
383+
if (ret < 0) {
384+
goto fallback;
385+
}
386+
387+
ret = video_query_ctrl(dev, &ctrl_query);
388+
if (ret < 0) {
389+
return ret;
390+
}
391+
392+
if (ctrl.val < ctrl_query.range.min || ctrl.val > ctrl_query.range.max) {
393+
return -EIO;
394+
}
395+
396+
return (int64_t)ctrl_query.int_menu[ctrl.val];
397+
398+
fallback:
399+
/* If VIDEO_CID_LINK_FREQUENCY is not available, approximate from VIDEO_CID_PIXEL_RATE */
400+
ctrl.id = VIDEO_CID_PIXEL_RATE;
401+
ret = video_get_ctrl(dev, &ctrl);
402+
if (ret < 0) {
403+
return ret;
404+
}
405+
406+
return ctrl.val64 * bpp / (2 * lane_nb);
407+
}

drivers/video/video_ctrls.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ 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_FREQUENCY:
112+
*type = VIDEO_CTRL_TYPE_MENU_INTEGER;
113+
*flags |= VIDEO_CTRL_FLAG_READ_ONLY;
114+
break;
111115
default:
112116
*type = VIDEO_CTRL_TYPE_INTEGER;
113117
break;
@@ -528,6 +532,8 @@ static inline const char *video_get_ctrl_name(uint32_t id)
528532
return "Pixel Rate";
529533
case VIDEO_CID_TEST_PATTERN:
530534
return "Test Pattern";
535+
case VIDEO_CID_LINK_FREQUENCY:
536+
return "Link Frequency";
531537
default:
532538
return NULL;
533539
}

include/zephyr/drivers/video-controls.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,9 @@ enum video_camera_orientation {
368368
/** Selection of the type of test pattern to represent */
369369
#define VIDEO_CID_TEST_PATTERN (VIDEO_CID_IMAGE_PROC_CLASS_BASE + 3)
370370

371+
/** Link frequency, applicable for the CSI2 based devices. This control is read-only. */
372+
#define VIDEO_CID_LINK_FREQUENCY (VIDEO_CID_IMAGE_PROC_CLASS_BASE + 4)
373+
371374
/**
372375
* @}
373376
*/

include/zephyr/drivers/video.h

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

807+
/**
808+
* @brief Return the link-frequency advertised by a device
809+
*
810+
* Device exposing a CSI link should advertise at least one of the following two controls:
811+
* - @ref VIDEO_CID_LINK_FREQUENCY
812+
* - @ref VIDEO_CID_PIXEL_RATE
813+
*
814+
* At first the helper will try read the @ref VIDEO_CID_LINK_FREQUENCY and if not available will
815+
* approximate the link-frequency from the @ref VIDEO_CID_PIXEL_RATE value, taking into
816+
* consideration the bits per pixel of the format and the number of lanes.
817+
*
818+
* @param dev Video device to query.
819+
* @param bpp Amount of bits per pixel of the pixel format produced by the device
820+
* @param lane_nb Number of CSI-2 lanes used
821+
*/
822+
int64_t video_get_link_frequency(const struct device *dev, uint8_t bpp, uint8_t lane_nb);
823+
807824
/**
808825
* @defgroup video_pixel_formats Video pixel formats
809826
* The '|' characters separate the pixels or logical blocks, and spaces separate the bytes.

0 commit comments

Comments
 (0)