18
18
#include <zephyr/drivers/i2c_emul.h>
19
19
#include <zephyr/logging/log.h>
20
20
21
+ #include "video_common.h"
21
22
#include "video_ctrls.h"
22
23
#include "video_device.h"
23
24
24
25
LOG_MODULE_REGISTER (video_emul_imager , CONFIG_VIDEO_LOG_LEVEL );
25
26
26
- #define EMUL_IMAGER_REG_SENSOR_ID 0x00
27
+ #define EMUL_IMAGER_REG8 (addr ) ((addr) | VIDEO_REG_ADDR8_DATA8)
28
+
29
+ #define EMUL_IMAGER_REG_SENSOR_ID EMUL_IMAGER_REG8(0x00)
27
30
#define EMUL_IMAGER_SENSOR_ID 0x99
28
- #define EMUL_IMAGER_REG_CTRL 0x01
29
- #define EMUL_IMAGER_REG_INIT1 0x02
30
- #define EMUL_IMAGER_REG_INIT2 0x03
31
- #define EMUL_IMAGER_REG_TIMING1 0x04
32
- #define EMUL_IMAGER_REG_TIMING2 0x05
33
- #define EMUL_IMAGER_REG_TIMING3 0x06
34
- #define EMUL_IMAGER_REG_CUSTOM 0x07
35
- #define EMUL_IMAGER_REG_FORMAT 0x0a
36
- #define EMUL_IMAGER_PATTERN_OFF 0x00
37
- #define EMUL_IMAGER_PATTERN_BARS1 0x01
38
- #define EMUL_IMAGER_PATTERN_BARS2 0x02
31
+ #define EMUL_IMAGER_REG_CTRL EMUL_IMAGER_REG8( 0x01)
32
+ #define EMUL_IMAGER_REG_INIT1 EMUL_IMAGER_REG8( 0x02)
33
+ #define EMUL_IMAGER_REG_INIT2 EMUL_IMAGER_REG8( 0x03)
34
+ #define EMUL_IMAGER_REG_TIMING1 EMUL_IMAGER_REG8( 0x04)
35
+ #define EMUL_IMAGER_REG_TIMING2 EMUL_IMAGER_REG8( 0x05)
36
+ #define EMUL_IMAGER_REG_TIMING3 EMUL_IMAGER_REG8( 0x06)
37
+ #define EMUL_IMAGER_REG_CUSTOM EMUL_IMAGER_REG8( 0x07)
38
+ #define EMUL_IMAGER_REG_FORMAT EMUL_IMAGER_REG8( 0x0a)
39
+ #define EMUL_IMAGER_PATTERN_OFF EMUL_IMAGER_REG8( 0x00)
40
+ #define EMUL_IMAGER_PATTERN_BARS1 EMUL_IMAGER_REG8( 0x01)
41
+ #define EMUL_IMAGER_PATTERN_BARS2 EMUL_IMAGER_REG8( 0x02)
39
42
40
43
/* Custom control that is just an I2C write for example and test purpose */
41
44
#define EMUL_IMAGER_CID_CUSTOM (VIDEO_CID_PRIVATE_BASE + 0x01)
42
45
46
+ /* Helper to avoid repetition */
47
+ #define EMUL_IMAGER_REG_LIST (array ) {.regs = (array), .size = ARRAY_SIZE(array)}
48
+
43
49
enum emul_imager_fmt_id {
44
50
RGB565_320x240 ,
45
51
YUYV_320x240 ,
46
52
};
47
53
48
- struct emul_imager_reg {
49
- uint16_t addr ;
50
- uint8_t value ;
54
+ struct emul_imager_reg_list {
55
+ const struct video_reg * regs ;
56
+ size_t size ;
51
57
};
52
58
53
59
struct emul_imager_mode {
@@ -56,8 +62,7 @@ struct emul_imager_mode {
56
62
* This permits to deduplicate the list of registers in case some lare sections
57
63
* are repeated across modes, such as the resolution for different FPS.
58
64
*/
59
- const struct emul_imager_reg * regs [3 ];
60
- /* More fields can be added according to the needs of the sensor driver */
65
+ const struct emul_imager_reg_list lists [3 ];
61
66
};
62
67
63
68
struct emul_imager_config {
@@ -79,53 +84,82 @@ struct emul_imager_data {
79
84
};
80
85
81
86
/* All the I2C registers sent on various scenario */
82
- static const struct emul_imager_reg emul_imager_init_regs [] = {
87
+ static const struct video_reg emul_imager_init_regs [] = {
83
88
{EMUL_IMAGER_REG_CTRL , 0x00 },
84
89
{EMUL_IMAGER_REG_INIT1 , 0x10 },
85
90
{EMUL_IMAGER_REG_INIT2 , 0x00 },
86
91
/* Undocumented registers from the vendor */
87
- {0x80 , 0x01 },
88
- {0x84 , 0x01 },
89
- {0x85 , 0x20 },
90
- {0x89 , 0x7f },
91
- {0 },
92
+ {EMUL_IMAGER_REG8 (0x80 ), 0x01 },
93
+ {EMUL_IMAGER_REG8 (0x84 ), 0x01 },
94
+ {EMUL_IMAGER_REG8 (0x85 ), 0x20 },
95
+ {EMUL_IMAGER_REG8 (0x89 ), 0x7f },
92
96
};
93
- static const struct emul_imager_reg emul_imager_rgb565 [] = {
97
+ static const struct video_reg emul_imager_rgb565 [] = {
94
98
{EMUL_IMAGER_REG_FORMAT , 0x01 },
95
- {0 },
96
99
};
97
- static const struct emul_imager_reg emul_imager_yuyv [] = {
100
+ static const struct video_reg emul_imager_yuyv [] = {
98
101
{EMUL_IMAGER_REG_FORMAT , 0x02 },
99
- {0 },
100
102
};
101
- static const struct emul_imager_reg emul_imager_320x240 [] = {
103
+ static const struct video_reg emul_imager_320x240 [] = {
102
104
{EMUL_IMAGER_REG_TIMING1 , 0x32 },
103
105
{EMUL_IMAGER_REG_TIMING2 , 0x24 },
104
- {0 },
105
106
};
106
- static const struct emul_imager_reg emul_imager_15fps [] = {
107
+ static const struct video_reg emul_imager_15fps [] = {
107
108
{EMUL_IMAGER_REG_TIMING3 , 15 },
108
- {0 },
109
109
};
110
- static const struct emul_imager_reg emul_imager_30fps [] = {
110
+ static const struct video_reg emul_imager_30fps [] = {
111
111
{EMUL_IMAGER_REG_TIMING3 , 30 },
112
- {0 },
113
112
};
114
- static const struct emul_imager_reg emul_imager_60fps [] = {
113
+ static const struct video_reg emul_imager_60fps [] = {
115
114
{EMUL_IMAGER_REG_TIMING3 , 60 },
116
- {0 },
117
115
};
118
116
119
117
/* Description of "modes", that pick lists of registesr that will be all sentto the imager */
120
118
struct emul_imager_mode emul_imager_rgb565_320x240_modes [] = {
121
- {.fps = 15 , .regs = {emul_imager_320x240 , emul_imager_rgb565 , emul_imager_15fps }},
122
- {.fps = 30 , .regs = {emul_imager_320x240 , emul_imager_rgb565 , emul_imager_30fps }},
123
- {.fps = 60 , .regs = {emul_imager_320x240 , emul_imager_rgb565 , emul_imager_60fps }},
119
+ {
120
+ .fps = 15 ,
121
+ .lists = {
122
+ EMUL_IMAGER_REG_LIST (emul_imager_320x240 ),
123
+ EMUL_IMAGER_REG_LIST (emul_imager_rgb565 ),
124
+ EMUL_IMAGER_REG_LIST (emul_imager_15fps ),
125
+ },
126
+ },
127
+ {
128
+ .fps = 30 ,
129
+ .lists = {
130
+ EMUL_IMAGER_REG_LIST (emul_imager_320x240 ),
131
+ EMUL_IMAGER_REG_LIST (emul_imager_rgb565 ),
132
+ EMUL_IMAGER_REG_LIST (emul_imager_30fps ),
133
+ },
134
+ },
135
+ {
136
+ .fps = 60 ,
137
+ .lists = {
138
+ EMUL_IMAGER_REG_LIST (emul_imager_320x240 ),
139
+ EMUL_IMAGER_REG_LIST (emul_imager_rgb565 ),
140
+ EMUL_IMAGER_REG_LIST (emul_imager_60fps ),
141
+ },
142
+ },
124
143
{0 },
125
144
};
145
+
126
146
struct emul_imager_mode emul_imager_yuyv_320x240_modes [] = {
127
- {.fps = 15 , .regs = {emul_imager_320x240 , emul_imager_yuyv , emul_imager_15fps }},
128
- {.fps = 30 , .regs = {emul_imager_320x240 , emul_imager_yuyv , emul_imager_30fps }},
147
+ {
148
+ .fps = 15 ,
149
+ .lists = {
150
+ EMUL_IMAGER_REG_LIST (emul_imager_320x240 ),
151
+ EMUL_IMAGER_REG_LIST (emul_imager_yuyv ),
152
+ EMUL_IMAGER_REG_LIST (emul_imager_15fps ),
153
+ }
154
+ },
155
+ {
156
+ .fps = 30 ,
157
+ .lists = {
158
+ EMUL_IMAGER_REG_LIST (emul_imager_320x240 ),
159
+ EMUL_IMAGER_REG_LIST (emul_imager_yuyv ),
160
+ EMUL_IMAGER_REG_LIST (emul_imager_30fps ),
161
+ }
162
+ },
129
163
{0 },
130
164
};
131
165
@@ -155,47 +189,18 @@ static const struct video_format_cap fmts[] = {
155
189
{0 },
156
190
};
157
191
158
- /* Emulated I2C register interface, to replace with actual I2C calls for real hardware */
159
- static int emul_imager_read_reg (const struct device * const dev , uint8_t reg_addr , uint8_t * value )
160
- {
161
- const struct emul_imager_config * cfg = dev -> config ;
162
-
163
- return i2c_write_read_dt (& cfg -> i2c , & reg_addr , 1 , value , 1 );
164
- }
165
-
166
- /* Some sensors will need reg8 or reg16 variants. */
167
- static int emul_imager_write_reg (const struct device * const dev , uint8_t reg_addr , uint8_t value )
168
- {
169
- const struct emul_imager_config * cfg = dev -> config ;
170
- uint8_t buf_w [] = {reg_addr , value };
171
-
172
- return i2c_write_dt (& cfg -> i2c , buf_w , 2 );
173
- }
174
-
175
- static int emul_imager_write_multi (const struct device * const dev ,
176
- const struct emul_imager_reg * regs )
177
- {
178
- int ret ;
179
-
180
- for (int i = 0 ; regs [i ].addr != 0 ; i ++ ) {
181
- ret = emul_imager_write_reg (dev , regs [i ].addr , regs [i ].value );
182
- if (ret < 0 ) {
183
- return ret ;
184
- }
185
- }
186
- return 0 ;
187
- }
188
-
189
192
static int emul_imager_set_ctrl (const struct device * dev , uint32_t id )
190
193
{
194
+ const struct emul_imager_config * cfg = dev -> config ;
191
195
struct emul_imager_data * data = dev -> data ;
192
196
193
- return emul_imager_write_reg ( dev , EMUL_IMAGER_REG_CUSTOM , data -> ctrls .custom .val );
197
+ return video_write_cci_reg ( & cfg -> i2c , EMUL_IMAGER_REG_CUSTOM , data -> ctrls .custom .val );
194
198
}
195
199
196
200
/* Customize this function according to your "struct emul_imager_mode". */
197
201
static int emul_imager_set_mode (const struct device * dev , const struct emul_imager_mode * mode )
198
202
{
203
+ const struct emul_imager_config * cfg = dev -> config ;
199
204
struct emul_imager_data * data = dev -> data ;
200
205
int ret ;
201
206
@@ -207,7 +212,9 @@ static int emul_imager_set_mode(const struct device *dev, const struct emul_imag
207
212
208
213
/* Apply all the configuration registers for that mode */
209
214
for (int i = 0 ; i < 2 ; i ++ ) {
210
- ret = emul_imager_write_multi (dev , mode -> regs [i ]);
215
+ const struct emul_imager_reg_list * list = & mode -> lists [i ];
216
+
217
+ ret = video_write_cci_multiregs (& cfg -> i2c , list -> regs , list -> size );
211
218
if (ret < 0 ) {
212
219
goto err ;
213
220
}
@@ -312,7 +319,9 @@ static int emul_imager_get_caps(const struct device *dev, struct video_caps *cap
312
319
313
320
static int emul_imager_set_stream (const struct device * dev , bool enable , enum video_buf_type type )
314
321
{
315
- return emul_imager_write_reg (dev , EMUL_IMAGER_REG_CTRL , enable ? 1 : 0 );
322
+ const struct emul_imager_config * cfg = dev -> config ;
323
+
324
+ return video_write_cci_reg (& cfg -> i2c , EMUL_IMAGER_REG_CTRL , enable ? 1 : 0 );
316
325
}
317
326
318
327
static DEVICE_API (video , emul_imager_driver_api ) = {
@@ -339,21 +348,22 @@ int emul_imager_init(const struct device *dev)
339
348
{
340
349
const struct emul_imager_config * cfg = dev -> config ;
341
350
struct video_format fmt ;
342
- uint8_t sensor_id ;
351
+ uint32_t sensor_id ;
343
352
int ret ;
344
353
345
354
if (!i2c_is_ready_dt (& cfg -> i2c )) {
346
355
LOG_ERR ("Bus %s is not ready" , cfg -> i2c .bus -> name );
347
356
return - ENODEV ;
348
357
}
349
358
350
- ret = emul_imager_read_reg ( dev , EMUL_IMAGER_REG_SENSOR_ID , & sensor_id );
359
+ ret = video_read_cci_reg ( & cfg -> i2c , EMUL_IMAGER_REG_SENSOR_ID , & sensor_id );
351
360
if (ret < 0 || sensor_id != EMUL_IMAGER_SENSOR_ID ) {
352
361
LOG_ERR ("Failed to get a correct sensor ID 0x%x" , sensor_id );
353
362
return ret ;
354
363
}
355
364
356
- ret = emul_imager_write_multi (dev , emul_imager_init_regs );
365
+ ret = video_write_cci_multiregs (& cfg -> i2c , emul_imager_init_regs ,
366
+ ARRAY_SIZE (emul_imager_init_regs ));
357
367
if (ret < 0 ) {
358
368
LOG_ERR ("Could not set initial registers" );
359
369
return ret ;
@@ -395,7 +405,7 @@ static int emul_imager_transfer_i2c(const struct emul *target, struct i2c_msg ms
395
405
int addr )
396
406
{
397
407
static uint8_t fake_regs [UINT8_MAX ] = {
398
- [EMUL_IMAGER_REG_SENSOR_ID ] = EMUL_IMAGER_SENSOR_ID ,
408
+ [EMUL_IMAGER_REG_SENSOR_ID & VIDEO_REG_ADDR_MASK ] = EMUL_IMAGER_SENSOR_ID ,
399
409
};
400
410
401
411
if (num_msgs == 0 ) {
0 commit comments