1818#include <zephyr/drivers/i2c_emul.h>
1919#include <zephyr/logging/log.h>
2020
21+ #include "video_common.h"
2122#include "video_ctrls.h"
2223#include "video_device.h"
2324
2425LOG_MODULE_REGISTER (video_emul_imager , CONFIG_VIDEO_LOG_LEVEL );
2526
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)
2730#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)
3942
4043/* Custom control that is just an I2C write for example and test purpose */
4144#define EMUL_IMAGER_CID_CUSTOM (VIDEO_CID_PRIVATE_BASE + 0x01)
4245
46+ /* Helper to avoid repetition */
47+ #define EMUL_IMAGER_REG_LIST (array ) {.regs = (array), .size = ARRAY_SIZE(array)}
48+
4349enum emul_imager_fmt_id {
4450 RGB565_320x240 ,
4551 YUYV_320x240 ,
4652};
4753
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 ;
5157};
5258
5359struct emul_imager_mode {
@@ -56,8 +62,7 @@ struct emul_imager_mode {
5662 * This permits to deduplicate the list of registers in case some lare sections
5763 * are repeated across modes, such as the resolution for different FPS.
5864 */
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 ];
6166};
6267
6368struct emul_imager_config {
@@ -79,53 +84,82 @@ struct emul_imager_data {
7984};
8085
8186/* 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 [] = {
8388 {EMUL_IMAGER_REG_CTRL , 0x00 },
8489 {EMUL_IMAGER_REG_INIT1 , 0x10 },
8590 {EMUL_IMAGER_REG_INIT2 , 0x00 },
8691 /* 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 },
9296};
93- static const struct emul_imager_reg emul_imager_rgb565 [] = {
97+ static const struct video_reg emul_imager_rgb565 [] = {
9498 {EMUL_IMAGER_REG_FORMAT , 0x01 },
95- {0 },
9699};
97- static const struct emul_imager_reg emul_imager_yuyv [] = {
100+ static const struct video_reg emul_imager_yuyv [] = {
98101 {EMUL_IMAGER_REG_FORMAT , 0x02 },
99- {0 },
100102};
101- static const struct emul_imager_reg emul_imager_320x240 [] = {
103+ static const struct video_reg emul_imager_320x240 [] = {
102104 {EMUL_IMAGER_REG_TIMING1 , 0x32 },
103105 {EMUL_IMAGER_REG_TIMING2 , 0x24 },
104- {0 },
105106};
106- static const struct emul_imager_reg emul_imager_15fps [] = {
107+ static const struct video_reg emul_imager_15fps [] = {
107108 {EMUL_IMAGER_REG_TIMING3 , 15 },
108- {0 },
109109};
110- static const struct emul_imager_reg emul_imager_30fps [] = {
110+ static const struct video_reg emul_imager_30fps [] = {
111111 {EMUL_IMAGER_REG_TIMING3 , 30 },
112- {0 },
113112};
114- static const struct emul_imager_reg emul_imager_60fps [] = {
113+ static const struct video_reg emul_imager_60fps [] = {
115114 {EMUL_IMAGER_REG_TIMING3 , 60 },
116- {0 },
117115};
118116
119117/* Description of "modes", that pick lists of registesr that will be all sentto the imager */
120118struct 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+ },
124143 {0 },
125144};
145+
126146struct 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+ },
129163 {0 },
130164};
131165
@@ -155,47 +189,18 @@ static const struct video_format_cap fmts[] = {
155189 {0 },
156190};
157191
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-
189192static int emul_imager_set_ctrl (const struct device * dev , uint32_t id )
190193{
194+ const struct emul_imager_config * cfg = dev -> config ;
191195 struct emul_imager_data * data = dev -> data ;
192196
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 );
194198}
195199
196200/* Customize this function according to your "struct emul_imager_mode". */
197201static int emul_imager_set_mode (const struct device * dev , const struct emul_imager_mode * mode )
198202{
203+ const struct emul_imager_config * cfg = dev -> config ;
199204 struct emul_imager_data * data = dev -> data ;
200205 int ret ;
201206
@@ -207,7 +212,9 @@ static int emul_imager_set_mode(const struct device *dev, const struct emul_imag
207212
208213 /* Apply all the configuration registers for that mode */
209214 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 );
211218 if (ret < 0 ) {
212219 goto err ;
213220 }
@@ -312,7 +319,9 @@ static int emul_imager_get_caps(const struct device *dev, struct video_caps *cap
312319
313320static int emul_imager_set_stream (const struct device * dev , bool enable , enum video_buf_type type )
314321{
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 );
316325}
317326
318327static DEVICE_API (video , emul_imager_driver_api ) = {
@@ -339,21 +348,22 @@ int emul_imager_init(const struct device *dev)
339348{
340349 const struct emul_imager_config * cfg = dev -> config ;
341350 struct video_format fmt ;
342- uint8_t sensor_id ;
351+ uint32_t sensor_id ;
343352 int ret ;
344353
345354 if (!i2c_is_ready_dt (& cfg -> i2c )) {
346355 LOG_ERR ("Bus %s is not ready" , cfg -> i2c .bus -> name );
347356 return - ENODEV ;
348357 }
349358
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 );
351360 if (ret < 0 || sensor_id != EMUL_IMAGER_SENSOR_ID ) {
352361 LOG_ERR ("Failed to get a correct sensor ID 0x%x" , sensor_id );
353362 return ret ;
354363 }
355364
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 ));
357367 if (ret < 0 ) {
358368 LOG_ERR ("Could not set initial registers" );
359369 return ret ;
@@ -395,7 +405,7 @@ static int emul_imager_transfer_i2c(const struct emul *target, struct i2c_msg ms
395405 int addr )
396406{
397407 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 ,
399409 };
400410
401411 if (num_msgs == 0 ) {
0 commit comments