@@ -44,6 +44,9 @@ static inline unsigned int video_pix_fmt_bpp(uint32_t pixelformat)
4444 case VIDEO_PIX_FMT_RGB565 :
4545 case VIDEO_PIX_FMT_YUYV :
4646 return 2 ;
47+ case VIDEO_PIX_FMT_XRGB32 :
48+ case VIDEO_PIX_FMT_XYUV32 :
49+ return 4 ;
4750 default :
4851 return 0 ;
4952 }
@@ -113,23 +116,62 @@ static void __frame_done_cb(CSI_Type *base, csi_handle_t *handle, status_t statu
113116 return ;
114117}
115118
119+ #if defined(CONFIG_VIDEO_MCUX_MIPI_CSI2RX )
120+ K_HEAP_DEFINE (csi_heap , 1000 );
121+ static struct video_format_cap * fmts ;
122+ /*
123+ * On i.MX RT11xx SoCs which have MIPI CSI-2 Rx, image data from the camera sensor after passing
124+ * through the pipeline (MIPI CSI-2 Rx --> Video Mux --> CSI) will be implicitly converted to a
125+ * 32-bits pixel format. For example, an input in RGB565 or YUYV (2-bytes format) will become a
126+ * XRGB32 or XYUV32 (4-bytes format) respectively, at the output of the CSI.
127+ */
128+ static inline void video_pix_fmt_convert (struct video_format * fmt , bool isGetFmt )
129+ {
130+ switch (fmt -> pixelformat ) {
131+ case VIDEO_PIX_FMT_XRGB32 :
132+ fmt -> pixelformat = isGetFmt ? VIDEO_PIX_FMT_XRGB32 : VIDEO_PIX_FMT_RGB565 ;
133+ break ;
134+ case VIDEO_PIX_FMT_XYUV32 :
135+ fmt -> pixelformat = isGetFmt ? VIDEO_PIX_FMT_XYUV32 : VIDEO_PIX_FMT_YUYV ;
136+ break ;
137+ case VIDEO_PIX_FMT_RGB565 :
138+ fmt -> pixelformat = isGetFmt ? VIDEO_PIX_FMT_XRGB32 : VIDEO_PIX_FMT_RGB565 ;
139+ break ;
140+ case VIDEO_PIX_FMT_YUYV :
141+ fmt -> pixelformat = isGetFmt ? VIDEO_PIX_FMT_XYUV32 : VIDEO_PIX_FMT_YUYV ;
142+ break ;
143+ }
144+
145+ fmt -> pitch = fmt -> width * video_pix_fmt_bpp (fmt -> pixelformat );
146+ }
147+ #endif
148+
116149static int video_mcux_csi_set_fmt (const struct device * dev , enum video_endpoint_id ep ,
117150 struct video_format * fmt )
118151{
119152 const struct video_mcux_csi_config * config = dev -> config ;
120153 struct video_mcux_csi_data * data = dev -> data ;
121154 unsigned int bpp = video_pix_fmt_bpp (fmt -> pixelformat );
122155 status_t ret ;
156+ struct video_format format = * fmt ;
123157
124158 if (!bpp || ep != VIDEO_EP_OUT ) {
125159 return - EINVAL ;
126160 }
127161
128162 data -> csi_config .bytesPerPixel = bpp ;
129163 data -> csi_config .linePitch_Bytes = fmt -> pitch ;
164+ #if defined(CONFIG_VIDEO_MCUX_MIPI_CSI2RX )
165+ if (fmt -> pixelformat != VIDEO_PIX_FMT_XRGB32 && fmt -> pixelformat != VIDEO_PIX_FMT_XYUV32 ) {
166+ return - ENOTSUP ;
167+ }
168+ video_pix_fmt_convert (& format , false);
169+ data -> csi_config .dataBus = kCSI_DataBus24Bit ;
170+ #else
171+ data -> csi_config .dataBus = kCSI_DataBus8Bit ;
172+ #endif
130173 data -> csi_config .polarityFlags = kCSI_HsyncActiveHigh | kCSI_DataLatchOnRisingEdge ;
131174 data -> csi_config .workMode = kCSI_GatedClockMode ; /* use VSYNC, HSYNC, and PIXCLK */
132- data -> csi_config .dataBus = kCSI_DataBus8Bit ;
133175 data -> csi_config .useExtVsync = true;
134176 data -> csi_config .height = fmt -> height ;
135177 data -> csi_config .width = fmt -> width ;
@@ -144,7 +186,7 @@ static int video_mcux_csi_set_fmt(const struct device *dev, enum video_endpoint_
144186 return - EIO ;
145187 }
146188
147- if (config -> source_dev && video_set_format (config -> source_dev , ep , fmt )) {
189+ if (config -> source_dev && video_set_format (config -> source_dev , ep , & format )) {
148190 return - EIO ;
149191 }
150192
@@ -161,6 +203,9 @@ static int video_mcux_csi_get_fmt(const struct device *dev, enum video_endpoint_
161203 }
162204
163205 if (config -> source_dev && !video_get_format (config -> source_dev , ep , fmt )) {
206+ #if defined(CONFIG_VIDEO_MCUX_MIPI_CSI2RX )
207+ video_pix_fmt_convert (fmt , true);
208+ #endif
164209 /* align CSI with source fmt */
165210 return video_mcux_csi_set_fmt (dev , ep , fmt );
166211 }
@@ -317,6 +362,34 @@ static int video_mcux_csi_get_caps(const struct device *dev, enum video_endpoint
317362 /* Just forward to source dev for now */
318363 if (config -> source_dev ) {
319364 err = video_get_caps (config -> source_dev , ep , caps );
365+ #if defined(CONFIG_VIDEO_MCUX_MIPI_CSI2RX )
366+ /*
367+ * On i.MX RT11xx SoCs which have MIPI CSI-2 Rx, image data from the camera sensor
368+ * after passing through the pipeline (MIPI CSI-2 Rx --> Video Mux --> CSI) will be
369+ * implicitly converted to a 32-bits pixel format. For example, an input in RGB565
370+ * or YUYV (2-bytes format) will become an XRGB32 or XYUV32 (4-bytes format)
371+ * respectively, at the output of the CSI. So, we change the pixel formats of the
372+ * source caps to reflect this.
373+ */
374+ int ind = 0 ;
375+
376+ while (caps -> format_caps [ind ].pixelformat ) {
377+ ind ++ ;
378+ }
379+ k_heap_free (& csi_heap , fmts );
380+ fmts = k_heap_alloc (& csi_heap , (ind + 1 ) * sizeof (struct video_format_cap ),
381+ K_FOREVER );
382+
383+ for (int i = 0 ; i <= ind ; i ++ ) {
384+ memcpy (& fmts [i ], & caps -> format_caps [i ], sizeof (fmts [i ]));
385+ if (fmts [i ].pixelformat == VIDEO_PIX_FMT_RGB565 ) {
386+ fmts [i ].pixelformat = VIDEO_PIX_FMT_XRGB32 ;
387+ } else if (fmts [i ].pixelformat == VIDEO_PIX_FMT_YUYV ) {
388+ fmts [i ].pixelformat = VIDEO_PIX_FMT_XYUV32 ;
389+ }
390+ }
391+ caps -> format_caps = fmts ;
392+ #endif
320393 }
321394
322395 /* NXP MCUX CSI request at least 2 buffer before starting */
0 commit comments