@@ -46,27 +46,9 @@ enum emul_imager_fmt_id {
46
46
YUYV_320x240 ,
47
47
};
48
48
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
-
63
49
struct emul_imager_data {
64
50
/* First field is a line buffer for I/O emulation purpose */
65
51
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 ;
70
52
};
71
53
72
54
/* All the I2C registers sent on various scenario */
@@ -108,47 +90,31 @@ static const struct video_reg emul_imager_60fps[] = {
108
90
};
109
91
110
92
/* 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 [] = {
112
94
{.fps = 15 , .regs = {emul_imager_320x240 , emul_imager_rgb565 , emul_imager_15fps }},
113
95
{.fps = 30 , .regs = {emul_imager_320x240 , emul_imager_rgb565 , emul_imager_30fps }},
114
96
{.fps = 60 , .regs = {emul_imager_320x240 , emul_imager_rgb565 , emul_imager_60fps }},
115
97
{0 },
116
98
};
117
- struct emul_imager_mode emul_imager_yuyv_320x240_modes [] = {
99
+ static struct video_imager_mode emul_imager_yuyv_320x240_modes [] = {
118
100
{.fps = 15 , .regs = {emul_imager_320x240 , emul_imager_yuyv , emul_imager_15fps }},
119
101
{.fps = 30 , .regs = {emul_imager_320x240 , emul_imager_yuyv , emul_imager_30fps }},
120
102
{0 },
121
103
};
122
104
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 [] = {
125
106
[RGB565_320x240 ] = emul_imager_rgb565_320x240_modes ,
126
107
[YUYV_320x240 ] = emul_imager_yuyv_320x240_modes ,
127
108
};
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 ),
146
112
{0 },
147
113
};
148
114
149
115
static int emul_imager_set_ctrl (const struct device * dev , unsigned int cid , void * value )
150
116
{
151
- const struct emul_imager_config * cfg = dev -> config ;
117
+ const struct video_imager_config * cfg = dev -> config ;
152
118
153
119
switch (cid ) {
154
120
case EMUL_IMAGER_CID_CUSTOM :
@@ -160,7 +126,7 @@ static int emul_imager_set_ctrl(const struct device *dev, unsigned int cid, void
160
126
161
127
static int emul_imager_get_ctrl (const struct device * dev , unsigned int cid , void * value )
162
128
{
163
- const struct emul_imager_config * cfg = dev -> config ;
129
+ const struct video_imager_config * cfg = dev -> config ;
164
130
uint32_t reg = 0 ;
165
131
int ret ;
166
132
@@ -176,178 +142,30 @@ static int emul_imager_get_ctrl(const struct device *dev, unsigned int cid, void
176
142
return ret ;
177
143
}
178
144
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
-
328
145
static int emul_imager_set_stream (const struct device * dev , bool enable )
329
146
{
330
- const struct emul_imager_config * cfg = dev -> config ;
147
+ const struct video_imager_config * cfg = dev -> config ;
331
148
332
149
return video_write_cci_reg (& cfg -> i2c , EMUL_IMAGER_REG_CTRL , enable ? 1 : 0 );
333
150
}
334
151
335
152
static DEVICE_API (video , emul_imager_driver_api ) = {
153
+ /* Local implementation */
336
154
.set_ctrl = emul_imager_set_ctrl ,
337
155
.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 ,
344
156
.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 ,
345
164
};
346
165
347
166
int emul_imager_init (const struct device * dev )
348
167
{
349
- const struct emul_imager_config * cfg = dev -> config ;
350
- struct video_format fmt ;
168
+ const struct video_imager_config * cfg = dev -> config ;
351
169
uint32_t sensor_id ;
352
170
int ret ;
353
171
@@ -362,35 +180,24 @@ int emul_imager_init(const struct device *dev)
362
180
return ret ;
363
181
}
364
182
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 );
383
184
}
384
185
385
186
#define EMUL_IMAGER_DEFINE (inst ) \
386
187
static struct emul_imager_data emul_imager_data_##inst; \
387
188
\
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 = { \
389
192
.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, \
390
197
}; \
391
198
\
392
199
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, \
394
201
&emul_imager_driver_api);
395
202
396
203
DT_INST_FOREACH_STATUS_OKAY (EMUL_IMAGER_DEFINE )
0 commit comments