Skip to content

Commit 1385de9

Browse files
trunghieulenxpngphibang
authored andcommitted
drivers: video: mcux_mipi_csi2rx: Add support for changing frame rate
Add support for changing frame rate. Signed-off-by: Trung Hieu Le <trunghieu.le@nxp.com> Signed-off-by: Phi Bang Nguyen <phibang.nguyen@nxp.com>
1 parent 425a1df commit 1385de9

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
@@ -7,6 +7,7 @@
77
#define DT_DRV_COMPAT nxp_mipi_csi2rx
88

99
#include <zephyr/drivers/video.h>
10+
#include <zephyr/drivers/video-controls.h>
1011
#include <zephyr/kernel.h>
1112
#include <zephyr/logging/log.h>
1213
#include <soc.h>
@@ -173,13 +174,125 @@ static inline int mipi_csi2rx_set_ctrl(const struct device *dev, unsigned int ci
173174
return -ENOTSUP;
174175
}
175176

177+
static int mipi_csi2rx_set_frmival(const struct device *dev, enum video_endpoint_id ep,
178+
struct video_frmival *frmival)
179+
{
180+
const struct mipi_csi2rx_config *config = dev->config;
181+
int ret;
182+
183+
ret = video_set_frmival(config->sensor_dev, ep, frmival);
184+
if (ret) {
185+
LOG_ERR("Cannot set sensor_dev frmival");
186+
return ret;
187+
}
188+
189+
ret = mipi_csi2rx_update_settings(dev, ep);
190+
191+
return ret;
192+
}
193+
194+
static int mipi_csi2rx_get_frmival(const struct device *dev, enum video_endpoint_id ep,
195+
struct video_frmival *frmival)
196+
{
197+
const struct mipi_csi2rx_config *config = dev->config;
198+
199+
return video_get_frmival(config->sensor_dev, ep, frmival);
200+
}
201+
202+
static uint64_t mipi_csi2rx_cal_frame_size(const struct video_format *fmt)
203+
{
204+
return fmt->height * fmt->width * video_pix_fmt_bpp(fmt->pixelformat) * 8;
205+
}
206+
207+
static uint64_t mipi_csi2rx_estimate_pixel_rate(const struct video_frmival *cur_fmival,
208+
const struct video_frmival *fie_frmival,
209+
const struct video_format *cur_format,
210+
const struct video_format *fie_format,
211+
uint64_t cur_pixel_rate, uint8_t laneNum)
212+
{
213+
return mipi_csi2rx_cal_frame_size(cur_format) * fie_frmival->denominator *
214+
cur_fmival->numerator * cur_pixel_rate /
215+
(mipi_csi2rx_cal_frame_size(fie_format) * fie_frmival->numerator *
216+
cur_fmival->denominator);
217+
}
218+
219+
static int mipi_csi2rx_enum_frmival(const struct device *dev, enum video_endpoint_id ep,
220+
struct video_frmival_enum *fie)
221+
{
222+
const struct mipi_csi2rx_config *config = dev->config;
223+
struct mipi_csi2rx_data *drv_data = dev->data;
224+
int ret;
225+
uint64_t cur_pixel_rate, est_pixel_rate;
226+
struct video_frmival cur_frmival;
227+
struct video_format cur_fmt;
228+
229+
ret = video_enum_frmival(config->sensor_dev, ep, fie);
230+
if (ret) {
231+
return ret;
232+
}
233+
234+
ret = video_get_ctrl(config->sensor_dev, VIDEO_CID_PIXEL_RATE, &cur_pixel_rate);
235+
if (ret) {
236+
LOG_ERR("Cannot get sensor_dev pixel rate");
237+
return ret;
238+
}
239+
240+
ret = video_get_frmival(config->sensor_dev, ep, &cur_frmival);
241+
if (ret) {
242+
LOG_ERR("Cannot get sensor_dev frame rate");
243+
return ret;
244+
}
245+
246+
ret = video_get_format(config->sensor_dev, ep, &cur_fmt);
247+
if (ret) {
248+
LOG_ERR("Cannot get sensor_dev format");
249+
return ret;
250+
}
251+
252+
if (fie->type == VIDEO_FRMIVAL_TYPE_DISCRETE) {
253+
est_pixel_rate = mipi_csi2rx_estimate_pixel_rate(
254+
&cur_frmival, &fie->discrete, &cur_fmt, fie->format, cur_pixel_rate,
255+
drv_data->csi2rxConfig.laneNum);
256+
if (est_pixel_rate > MAX_SUPPORTED_PIXEL_RATE) {
257+
return -EINVAL;
258+
}
259+
260+
} else {
261+
/* Check the lane rate of the lower bound framerate */
262+
est_pixel_rate = mipi_csi2rx_estimate_pixel_rate(
263+
&cur_frmival, &fie->stepwise.min, &cur_fmt, fie->format, cur_pixel_rate,
264+
drv_data->csi2rxConfig.laneNum);
265+
if (est_pixel_rate > MAX_SUPPORTED_PIXEL_RATE) {
266+
return -EINVAL;
267+
}
268+
269+
/* Check the lane rate of the upper bound framerate */
270+
est_pixel_rate = mipi_csi2rx_estimate_pixel_rate(
271+
&cur_frmival, &fie->stepwise.max, &cur_fmt, fie->format, cur_pixel_rate,
272+
drv_data->csi2rxConfig.laneNum);
273+
if (est_pixel_rate > MAX_SUPPORTED_PIXEL_RATE) {
274+
fie->stepwise.max.denominator =
275+
(mipi_csi2rx_cal_frame_size(&cur_fmt) * MAX_SUPPORTED_PIXEL_RATE *
276+
cur_frmival.denominator) /
277+
(mipi_csi2rx_cal_frame_size(fie->format) * cur_pixel_rate *
278+
cur_frmival.numerator);
279+
fie->stepwise.max.numerator = 1;
280+
}
281+
}
282+
283+
return 0;
284+
}
285+
176286
static const struct video_driver_api mipi_csi2rx_driver_api = {
177287
.get_caps = mipi_csi2rx_get_caps,
178288
.get_format = mipi_csi2rx_get_fmt,
179289
.set_format = mipi_csi2rx_set_fmt,
180290
.stream_start = mipi_csi2rx_stream_start,
181291
.stream_stop = mipi_csi2rx_stream_stop,
182292
.set_ctrl = mipi_csi2rx_set_ctrl,
293+
.set_frmival = mipi_csi2rx_set_frmival,
294+
.get_frmival = mipi_csi2rx_get_frmival,
295+
.enum_frmival = mipi_csi2rx_enum_frmival,
183296
};
184297

185298
static int mipi_csi2rx_init(const struct device *dev)

0 commit comments

Comments
 (0)