Skip to content

Commit 8053b72

Browse files
trunghieulenxphenrikbrixandersen
authored andcommitted
drivers: video: mipi_csi2rx: Add support for changing frame rate
Add support for changing frame rate. Signed-off-by: Trung Hieu Le <[email protected]> Signed-off-by: Phi Bang Nguyen <[email protected]>
1 parent a182394 commit 8053b72

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

drivers/video/video_mcux_mipi_csi2rx.c

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <zephyr/drivers/clock_control.h>
1010
#include <zephyr/drivers/video.h>
11+
#include <zephyr/drivers/video-controls.h>
1112
#include <zephyr/kernel.h>
1213
#include <zephyr/logging/log.h>
1314
#include <soc.h>
@@ -201,13 +202,125 @@ static inline int mipi_csi2rx_set_ctrl(const struct device *dev, unsigned int ci
201202
return -ENOTSUP;
202203
}
203204

205+
static int mipi_csi2rx_set_frmival(const struct device *dev, enum video_endpoint_id ep,
206+
struct video_frmival *frmival)
207+
{
208+
const struct mipi_csi2rx_config *config = dev->config;
209+
int ret;
210+
211+
ret = video_set_frmival(config->sensor_dev, ep, frmival);
212+
if (ret) {
213+
LOG_ERR("Cannot set sensor_dev frmival");
214+
return ret;
215+
}
216+
217+
ret = mipi_csi2rx_update_settings(dev, ep);
218+
219+
return ret;
220+
}
221+
222+
static int mipi_csi2rx_get_frmival(const struct device *dev, enum video_endpoint_id ep,
223+
struct video_frmival *frmival)
224+
{
225+
const struct mipi_csi2rx_config *config = dev->config;
226+
227+
return video_get_frmival(config->sensor_dev, ep, frmival);
228+
}
229+
230+
static uint64_t mipi_csi2rx_cal_frame_size(const struct video_format *fmt)
231+
{
232+
return fmt->height * fmt->width * video_pix_fmt_bpp(fmt->pixelformat) * 8;
233+
}
234+
235+
static uint64_t mipi_csi2rx_estimate_pixel_rate(const struct video_frmival *cur_fmival,
236+
const struct video_frmival *fie_frmival,
237+
const struct video_format *cur_format,
238+
const struct video_format *fie_format,
239+
uint64_t cur_pixel_rate, uint8_t laneNum)
240+
{
241+
return mipi_csi2rx_cal_frame_size(cur_format) * fie_frmival->denominator *
242+
cur_fmival->numerator * cur_pixel_rate /
243+
(mipi_csi2rx_cal_frame_size(fie_format) * fie_frmival->numerator *
244+
cur_fmival->denominator);
245+
}
246+
247+
static int mipi_csi2rx_enum_frmival(const struct device *dev, enum video_endpoint_id ep,
248+
struct video_frmival_enum *fie)
249+
{
250+
const struct mipi_csi2rx_config *config = dev->config;
251+
struct mipi_csi2rx_data *drv_data = dev->data;
252+
int ret;
253+
uint64_t cur_pixel_rate, est_pixel_rate;
254+
struct video_frmival cur_frmival;
255+
struct video_format cur_fmt;
256+
257+
ret = video_enum_frmival(config->sensor_dev, ep, fie);
258+
if (ret) {
259+
return ret;
260+
}
261+
262+
ret = video_get_ctrl(config->sensor_dev, VIDEO_CID_PIXEL_RATE, &cur_pixel_rate);
263+
if (ret) {
264+
LOG_ERR("Cannot get sensor_dev pixel rate");
265+
return ret;
266+
}
267+
268+
ret = video_get_frmival(config->sensor_dev, ep, &cur_frmival);
269+
if (ret) {
270+
LOG_ERR("Cannot get sensor_dev frame rate");
271+
return ret;
272+
}
273+
274+
ret = video_get_format(config->sensor_dev, ep, &cur_fmt);
275+
if (ret) {
276+
LOG_ERR("Cannot get sensor_dev format");
277+
return ret;
278+
}
279+
280+
if (fie->type == VIDEO_FRMIVAL_TYPE_DISCRETE) {
281+
est_pixel_rate = mipi_csi2rx_estimate_pixel_rate(
282+
&cur_frmival, &fie->discrete, &cur_fmt, fie->format, cur_pixel_rate,
283+
drv_data->csi2rxConfig.laneNum);
284+
if (est_pixel_rate > MAX_SUPPORTED_PIXEL_RATE) {
285+
return -EINVAL;
286+
}
287+
288+
} else {
289+
/* Check the lane rate of the lower bound framerate */
290+
est_pixel_rate = mipi_csi2rx_estimate_pixel_rate(
291+
&cur_frmival, &fie->stepwise.min, &cur_fmt, fie->format, cur_pixel_rate,
292+
drv_data->csi2rxConfig.laneNum);
293+
if (est_pixel_rate > MAX_SUPPORTED_PIXEL_RATE) {
294+
return -EINVAL;
295+
}
296+
297+
/* Check the lane rate of the upper bound framerate */
298+
est_pixel_rate = mipi_csi2rx_estimate_pixel_rate(
299+
&cur_frmival, &fie->stepwise.max, &cur_fmt, fie->format, cur_pixel_rate,
300+
drv_data->csi2rxConfig.laneNum);
301+
if (est_pixel_rate > MAX_SUPPORTED_PIXEL_RATE) {
302+
fie->stepwise.max.denominator =
303+
(mipi_csi2rx_cal_frame_size(&cur_fmt) * MAX_SUPPORTED_PIXEL_RATE *
304+
cur_frmival.denominator) /
305+
(mipi_csi2rx_cal_frame_size(fie->format) * cur_pixel_rate *
306+
cur_frmival.numerator);
307+
fie->stepwise.max.numerator = 1;
308+
}
309+
}
310+
311+
return 0;
312+
}
313+
204314
static const struct video_driver_api mipi_csi2rx_driver_api = {
205315
.get_caps = mipi_csi2rx_get_caps,
206316
.get_format = mipi_csi2rx_get_fmt,
207317
.set_format = mipi_csi2rx_set_fmt,
208318
.stream_start = mipi_csi2rx_stream_start,
209319
.stream_stop = mipi_csi2rx_stream_stop,
210320
.set_ctrl = mipi_csi2rx_set_ctrl,
321+
.set_frmival = mipi_csi2rx_set_frmival,
322+
.get_frmival = mipi_csi2rx_get_frmival,
323+
.enum_frmival = mipi_csi2rx_enum_frmival,
211324
};
212325

213326
static int mipi_csi2rx_init(const struct device *dev)

0 commit comments

Comments
 (0)