@@ -46,27 +46,9 @@ enum emul_imager_fmt_id {
4646 YUYV_320x240 ,
4747};
4848
49- struct emul_imager_mode {
50- uint8_t fps ;
51- /* List of registers lists to configure the various properties of the sensor.
52- * This permits to deduplicate the list of registers in case some lare sections
53- * are repeated across modes, such as the resolution for different FPS.
54- */
55- const struct video_reg * regs [3 ];
56- /* More fields can be added according to the needs of the sensor driver */
57- };
58-
59- struct emul_imager_config {
60- struct i2c_dt_spec i2c ;
61- };
62-
6349struct emul_imager_data {
6450 /* First field is a line buffer for I/O emulation purpose */
6551 uint8_t framebuffer [320 * sizeof (uint16_t )];
66- /* Other fields are shared with real hardware drivers */
67- const struct emul_imager_mode * mode ;
68- enum emul_imager_fmt_id fmt_id ;
69- struct video_format fmt ;
7052};
7153
7254/* All the I2C registers sent on various scenario */
@@ -108,47 +90,31 @@ static const struct video_reg emul_imager_60fps[] = {
10890};
10991
11092/* Description of "modes", that pick lists of registesr that will be all sentto the imager */
111- struct emul_imager_mode emul_imager_rgb565_320x240_modes [] = {
93+ static struct video_imager_mode emul_imager_rgb565_320x240_modes [] = {
11294 {.fps = 15 , .regs = {emul_imager_320x240 , emul_imager_rgb565 , emul_imager_15fps }},
11395 {.fps = 30 , .regs = {emul_imager_320x240 , emul_imager_rgb565 , emul_imager_30fps }},
11496 {.fps = 60 , .regs = {emul_imager_320x240 , emul_imager_rgb565 , emul_imager_60fps }},
11597 {0 },
11698};
117- struct emul_imager_mode emul_imager_yuyv_320x240_modes [] = {
99+ static struct video_imager_mode emul_imager_yuyv_320x240_modes [] = {
118100 {.fps = 15 , .regs = {emul_imager_320x240 , emul_imager_yuyv , emul_imager_15fps }},
119101 {.fps = 30 , .regs = {emul_imager_320x240 , emul_imager_yuyv , emul_imager_30fps }},
120102 {0 },
121103};
122104
123- /* Summary of all the modes of all the frame formats, with indexes matching those of fmts[]. */
124- static const struct emul_imager_mode * emul_imager_modes [] = {
105+ static const struct video_imager_mode * emul_imager_modes [] = {
125106 [RGB565_320x240 ] = emul_imager_rgb565_320x240_modes ,
126107 [YUYV_320x240 ] = emul_imager_yuyv_320x240_modes ,
127108};
128-
129- /* Video device capabilities where the supported resolutions and pixel formats are listed.
130- * The format ID is used as index to fetch the matching mode from the list above.
131- */
132- #define EMUL_IMAGER_VIDEO_FORMAT_CAP (format , width , height ) \
133- { \
134- /* For a real imager, the width and height would be macro parameters */ \
135- .pixelformat = (format), \
136- .width_min = (width), \
137- .width_max = (width), \
138- .width_step = 0, \
139- .height_min = (height), \
140- .height_max = (height), \
141- .height_step = 0, \
142- }
143- static const struct video_format_cap fmts [] = {
144- [RGB565_320x240 ] = EMUL_IMAGER_VIDEO_FORMAT_CAP (VIDEO_PIX_FMT_RGB565 , 320 , 240 ),
145- [YUYV_320x240 ] = EMUL_IMAGER_VIDEO_FORMAT_CAP (VIDEO_PIX_FMT_YUYV , 320 , 240 ),
109+ static const struct video_format_cap emul_imager_fmts [] = {
110+ [RGB565_320x240 ] = VIDEO_IMAGER_FORMAT_CAP (VIDEO_PIX_FMT_RGB565 , 320 , 240 ),
111+ [YUYV_320x240 ] = VIDEO_IMAGER_FORMAT_CAP (VIDEO_PIX_FMT_YUYV , 320 , 240 ),
146112 {0 },
147113};
148114
149115static int emul_imager_set_ctrl (const struct device * dev , unsigned int cid , void * value )
150116{
151- const struct emul_imager_config * cfg = dev -> config ;
117+ const struct video_imager_config * cfg = dev -> config ;
152118
153119 switch (cid ) {
154120 case EMUL_IMAGER_CID_CUSTOM :
@@ -160,7 +126,7 @@ static int emul_imager_set_ctrl(const struct device *dev, unsigned int cid, void
160126
161127static int emul_imager_get_ctrl (const struct device * dev , unsigned int cid , void * value )
162128{
163- const struct emul_imager_config * cfg = dev -> config ;
129+ const struct video_imager_config * cfg = dev -> config ;
164130 uint32_t reg = 0 ;
165131 int ret ;
166132
@@ -176,178 +142,30 @@ static int emul_imager_get_ctrl(const struct device *dev, unsigned int cid, void
176142 return ret ;
177143}
178144
179- /* Customize this function according to your "struct emul_imager_mode". */
180- static int emul_imager_set_mode (const struct device * dev , const struct emul_imager_mode * mode )
181- {
182- const struct emul_imager_config * cfg = dev -> config ;
183- struct emul_imager_data * data = dev -> data ;
184- int ret ;
185-
186- if (data -> mode == mode ) {
187- return 0 ;
188- }
189-
190- LOG_DBG ("Applying mode %p at %d FPS" , mode , mode -> fps );
191-
192- /* Apply all the configuration registers for that mode */
193- for (int i = 0 ; i < 2 ; i ++ ) {
194- ret = video_write_cci_multi (& cfg -> i2c , mode -> regs [i ]);
195- if (ret < 0 ) {
196- goto err ;
197- }
198- }
199-
200- data -> mode = mode ;
201- return 0 ;
202- err :
203- LOG_ERR ("Could not apply mode %p (%u FPS)" , mode , mode -> fps );
204- return ret ;
205- }
206-
207- static int emul_imager_set_frmival (const struct device * dev , enum video_endpoint_id ep ,
208- struct video_frmival * frmival )
209- {
210- struct emul_imager_data * data = dev -> data ;
211- struct video_frmival_enum fie = {.format = & data -> fmt , .discrete = * frmival };
212-
213- if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL ) {
214- return - EINVAL ;
215- }
216-
217- video_closest_frmival (dev , ep , & fie );
218- LOG_DBG ("Applying frame interval number %u" , fie .index );
219- return emul_imager_set_mode (dev , & emul_imager_modes [data -> fmt_id ][fie .index ]);
220- }
221-
222- static int emul_imager_get_frmival (const struct device * dev , enum video_endpoint_id ep ,
223- struct video_frmival * frmival )
224- {
225- struct emul_imager_data * data = dev -> data ;
226-
227- if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL ) {
228- return - EINVAL ;
229- }
230-
231- frmival -> numerator = 1 ;
232- frmival -> denominator = data -> mode -> fps ;
233- return 0 ;
234- }
235-
236- static int emul_imager_enum_frmival (const struct device * dev , enum video_endpoint_id ep ,
237- struct video_frmival_enum * fie )
238- {
239- const struct emul_imager_mode * mode ;
240- size_t fmt_id ;
241- int ret ;
242-
243- if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL ) {
244- return - EINVAL ;
245- }
246-
247- ret = video_format_caps_index (fmts , fie -> format , & fmt_id );
248- if (ret < 0 ) {
249- return ret ;
250- }
251-
252- mode = & emul_imager_modes [fmt_id ][fie -> index ];
253-
254- fie -> type = VIDEO_FRMIVAL_TYPE_DISCRETE ;
255- fie -> discrete .numerator = 1 ;
256- fie -> discrete .denominator = mode -> fps ;
257- fie -> index ++ ;
258-
259- return mode -> fps == 0 ;
260- }
261-
262- static int emul_imager_set_fmt (const struct device * const dev , enum video_endpoint_id ep ,
263- struct video_format * fmt )
264- {
265- struct emul_imager_data * data = dev -> data ;
266- size_t fmt_id ;
267- int ret ;
268-
269- if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL ) {
270- return - EINVAL ;
271- }
272-
273- if (memcmp (& data -> fmt , fmt , sizeof (data -> fmt )) == 0 ) {
274- return 0 ;
275- }
276-
277- ret = video_format_caps_index (fmts , fmt , & fmt_id );
278- if (ret < 0 ) {
279- LOG_ERR ("Format %x %ux%u not found" , fmt -> pixelformat , fmt -> width , fmt -> height );
280- return ret ;
281- }
282-
283- ret = emul_imager_set_mode (dev , & emul_imager_modes [fmt_id ][0 ]);
284- if (ret < 0 ) {
285- return ret ;
286- }
287-
288- /* For the purpose of simulation, fill the image line buffer with 50% gray, this data
289- * will be collected by the video_emul_rx driver.
290- */
291- if (fmt -> pixelformat == VIDEO_PIX_FMT_RGB565 ) {
292- for (int i = 0 ; i < fmt -> width ; i ++ ) {
293- ((uint16_t * )data -> framebuffer )[i ] = sys_cpu_to_le16 (0x7bef );
294- }
295- } else {
296- memset (data -> framebuffer , 0x7f , fmt -> pitch );
297- }
298-
299- data -> fmt_id = fmt_id ;
300- data -> fmt = * fmt ;
301- return 0 ;
302- }
303-
304- static int emul_imager_get_fmt (const struct device * dev , enum video_endpoint_id ep ,
305- struct video_format * fmt )
306- {
307- struct emul_imager_data * data = dev -> data ;
308-
309- if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL ) {
310- return - EINVAL ;
311- }
312-
313- * fmt = data -> fmt ;
314- return 0 ;
315- }
316-
317- static int emul_imager_get_caps (const struct device * dev , enum video_endpoint_id ep ,
318- struct video_caps * caps )
319- {
320- if (ep != VIDEO_EP_OUT && ep != VIDEO_EP_ALL ) {
321- return - EINVAL ;
322- }
323-
324- caps -> format_caps = fmts ;
325- return 0 ;
326- }
327-
328145static int emul_imager_set_stream (const struct device * dev , bool enable )
329146{
330- const struct emul_imager_config * cfg = dev -> config ;
147+ const struct video_imager_config * cfg = dev -> config ;
331148
332149 return video_write_cci_reg (& cfg -> i2c , EMUL_IMAGER_REG_CTRL , enable ? 1 : 0 );
333150}
334151
335152static DEVICE_API (video , emul_imager_driver_api ) = {
153+ /* Local implementation */
336154 .set_ctrl = emul_imager_set_ctrl ,
337155 .get_ctrl = emul_imager_get_ctrl ,
338- .set_frmival = emul_imager_set_frmival ,
339- .get_frmival = emul_imager_get_frmival ,
340- .enum_frmival = emul_imager_enum_frmival ,
341- .set_format = emul_imager_set_fmt ,
342- .get_format = emul_imager_get_fmt ,
343- .get_caps = emul_imager_get_caps ,
344156 .set_stream = emul_imager_set_stream ,
157+ /* Default implementation */
158+ .set_frmival = video_imager_set_frmival ,
159+ .get_frmival = video_imager_get_frmival ,
160+ .enum_frmival = video_imager_enum_frmival ,
161+ .set_format = video_imager_set_fmt ,
162+ .get_format = video_imager_get_fmt ,
163+ .get_caps = video_imager_get_caps ,
345164};
346165
347166int emul_imager_init (const struct device * dev )
348167{
349- const struct emul_imager_config * cfg = dev -> config ;
350- struct video_format fmt ;
168+ const struct video_imager_config * cfg = dev -> config ;
351169 uint32_t sensor_id ;
352170 int ret ;
353171
@@ -362,35 +180,24 @@ int emul_imager_init(const struct device *dev)
362180 return ret ;
363181 }
364182
365- ret = video_write_cci_multi (& cfg -> i2c , emul_imager_init_regs );
366- if (ret < 0 ) {
367- LOG_ERR ("Could not set initial registers" );
368- return ret ;
369- }
370-
371- fmt .pixelformat = fmts [0 ].pixelformat ;
372- fmt .width = fmts [0 ].width_min ;
373- fmt .height = fmts [0 ].height_min ;
374- fmt .pitch = fmt .width * 2 ;
375-
376- ret = emul_imager_set_fmt (dev , VIDEO_EP_OUT , & fmt );
377- if (ret < 0 ) {
378- LOG_ERR ("Failed to set to default format %x %ux%u" ,
379- fmt .pixelformat , fmt .width , fmt .height );
380- }
381-
382- return 0 ;
183+ return video_imager_init (dev , emul_imager_init_regs , 0 );
383184}
384185
385186#define EMUL_IMAGER_DEFINE (inst ) \
386187 static struct emul_imager_data emul_imager_data_##inst; \
387188 \
388- static const struct emul_imager_config emul_imager_cfg_##inst = { \
189+ static struct video_imager_data video_imager_data_##inst; \
190+ \
191+ static const struct video_imager_config video_imager_cfg_##inst = { \
389192 .i2c = I2C_DT_SPEC_INST_GET(inst), \
193+ .modes = emul_imager_modes, \
194+ .fmts = emul_imager_fmts, \
195+ .data = &video_imager_data_##inst, \
196+ .write_multi = video_write_cci_multi, \
390197 }; \
391198 \
392199 DEVICE_DT_INST_DEFINE(inst, &emul_imager_init, NULL, &emul_imager_data_##inst, \
393- &emul_imager_cfg_ ##inst, POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, \
200+ &video_imager_cfg_ ##inst, POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, \
394201 &emul_imager_driver_api);
395202
396203DT_INST_FOREACH_STATUS_OKAY (EMUL_IMAGER_DEFINE )
0 commit comments