1515#include <zephyr/drivers/video.h>
1616#include <zephyr/drivers/video-controls.h>
1717#include <zephyr/drivers/i2c.h>
18+ #include <zephyr/drivers/i2c_emul.h>
1819#include <zephyr/logging/log.h>
1920
2021#include "video_ctrls.h"
2122#include "video_device.h"
2223
2324LOG_MODULE_REGISTER (video_emul_imager , CONFIG_VIDEO_LOG_LEVEL );
2425
25- #define EMUL_IMAGER_REG_SENSOR_ID 0x0000
26+ #define EMUL_IMAGER_REG_SENSOR_ID 0x00
2627#define EMUL_IMAGER_SENSOR_ID 0x99
27- #define EMUL_IMAGER_REG_CTRL 0x0001
28- #define EMUL_IMAGER_REG_INIT1 0x0002
29- #define EMUL_IMAGER_REG_INIT2 0x0003
30- #define EMUL_IMAGER_REG_TIMING1 0x0004
31- #define EMUL_IMAGER_REG_TIMING2 0x0005
32- #define EMUL_IMAGER_REG_TIMING3 0x0006
33- #define EMUL_IMAGER_REG_CUSTOM 0x0007
34- #define EMUL_IMAGER_REG_FORMAT 0x000a
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
3536#define EMUL_IMAGER_PATTERN_OFF 0x00
3637#define EMUL_IMAGER_PATTERN_BARS1 0x01
3738#define EMUL_IMAGER_PATTERN_BARS2 0x02
3839
3940/* Custom control that is just an I2C write for example and test purpose */
4041#define EMUL_IMAGER_CID_CUSTOM (VIDEO_CID_PRIVATE_BASE + 0x01)
4142
42- /* Emulated register bank */
43- uint8_t emul_imager_fake_regs [10 ];
44-
4543enum emul_imager_fmt_id {
4644 RGB565_320x240 ,
4745 YUYV_320x240 ,
@@ -86,10 +84,10 @@ static const struct emul_imager_reg emul_imager_init_regs[] = {
8684 {EMUL_IMAGER_REG_INIT1 , 0x10 },
8785 {EMUL_IMAGER_REG_INIT2 , 0x00 },
8886 /* Undocumented registers from the vendor */
89- {0x1200 , 0x01 },
90- {0x1204 , 0x01 },
91- {0x1205 , 0x20 },
92- {0x1209 , 0x7f },
87+ {0x80 , 0x01 },
88+ {0x84 , 0x01 },
89+ {0x85 , 0x20 },
90+ {0x89 , 0x7f },
9391 {0 },
9492};
9593static const struct emul_imager_reg emul_imager_rgb565 [] = {
@@ -160,23 +158,18 @@ static const struct video_format_cap fmts[] = {
160158/* Emulated I2C register interface, to replace with actual I2C calls for real hardware */
161159static int emul_imager_read_reg (const struct device * const dev , uint8_t reg_addr , uint8_t * value )
162160{
163- LOG_DBG ("Placeholder for I2C read from 0x%02x" , reg_addr );
164- switch (reg_addr ) {
165- case EMUL_IMAGER_REG_SENSOR_ID :
166- * value = EMUL_IMAGER_SENSOR_ID ;
167- break ;
168- default :
169- * value = emul_imager_fake_regs [reg_addr ];
170- }
171- return 0 ;
161+ const struct emul_imager_config * cfg = dev -> config ;
162+
163+ return i2c_write_read_dt (& cfg -> i2c , & reg_addr , 1 , value , 1 );
172164}
173165
174166/* Some sensors will need reg8 or reg16 variants. */
175167static int emul_imager_write_reg (const struct device * const dev , uint8_t reg_addr , uint8_t value )
176168{
177- LOG_DBG ("Placeholder for I2C write 0x%08x to 0x%02x" , value , reg_addr );
178- emul_imager_fake_regs [reg_addr ] = value ;
179- return 0 ;
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 );
180173}
181174
182175static int emul_imager_write_multi (const struct device * const dev ,
@@ -375,12 +368,13 @@ static int emul_imager_init_controls(const struct device *dev)
375368
376369int emul_imager_init (const struct device * dev )
377370{
371+ const struct emul_imager_config * cfg = dev -> config ;
378372 struct video_format fmt ;
379373 uint8_t sensor_id ;
380374 int ret ;
381375
382- if (/* !i2c_is_ready_dt(&cfg->i2c) */ false ) {
383- /* LOG_ERR("Bus %s is not ready", cfg->i2c.bus->name); */
376+ if (!i2c_is_ready_dt (& cfg -> i2c )) {
377+ LOG_ERR ("Bus %s is not ready" , cfg -> i2c .bus -> name );
384378 return - ENODEV ;
385379 }
386380
@@ -415,7 +409,7 @@ int emul_imager_init(const struct device *dev)
415409 static struct emul_imager_data emul_imager_data_##inst; \
416410 \
417411 static const struct emul_imager_config emul_imager_cfg_##inst = { \
418- .i2c = /* I2C_DT_SPEC_INST_GET(inst) */ { 0 }, \
412+ .i2c = I2C_DT_SPEC_INST_GET(inst), \
419413 }; \
420414 \
421415 DEVICE_DT_INST_DEFINE(inst, &emul_imager_init, NULL, &emul_imager_data_##inst, \
@@ -425,3 +419,50 @@ int emul_imager_init(const struct device *dev)
425419 VIDEO_DEVICE_DEFINE(emul_imager_##inst, DEVICE_DT_INST_GET(inst), NULL);
426420
427421DT_INST_FOREACH_STATUS_OKAY (EMUL_IMAGER_DEFINE )
422+
423+ /* Simulated I2C bus */
424+
425+ static int emul_imager_transfer_i2c (const struct emul * target , struct i2c_msg msgs [], int num_msgs ,
426+ int addr )
427+ {
428+ static uint8_t fake_regs [UINT8_MAX ] = {
429+ [EMUL_IMAGER_REG_SENSOR_ID ] = EMUL_IMAGER_SENSOR_ID ,
430+ };
431+
432+ if (num_msgs == 0 ) {
433+ CODE_UNREACHABLE ;
434+ } else if (num_msgs == 1 &&
435+ msgs [0 ].len == 2 && (msgs [0 ].flags & I2C_MSG_READ ) == 0 ) {
436+ /* Register write */
437+ fake_regs [msgs [0 ].buf [0 ]] = msgs [0 ].buf [1 ];
438+ } else if (num_msgs == 2 &&
439+ msgs [0 ].len == 1 && (msgs [0 ].flags & I2C_MSG_READ ) == 0 &&
440+ msgs [1 ].len == 1 && (msgs [1 ].flags & I2C_MSG_READ ) == 0 ) {
441+ /* Register write */
442+ fake_regs [msgs [0 ].buf [0 ]] = msgs [1 ].buf [0 ];
443+ } else if (num_msgs == 2 &&
444+ msgs [0 ].len == 1 && (msgs [0 ].flags & I2C_MSG_READ ) == 0 &&
445+ msgs [1 ].len == 1 && (msgs [1 ].flags & I2C_MSG_READ ) != 0 ) {
446+ /* Register read */
447+ msgs [1 ].buf [0 ] = fake_regs [msgs [0 ].buf [0 ]];
448+ } else {
449+ LOG_ERR ("Unsupported I2C operation of %u messages" , num_msgs );
450+ return - EIO ;
451+ }
452+
453+ return 0 ;
454+ }
455+
456+ static const struct i2c_emul_api emul_imager_i2c_api = {
457+ .transfer = emul_imager_transfer_i2c ,
458+ };
459+
460+ static int emul_imager_init_i2c (const struct emul * target , const struct device * dev )
461+ {
462+ return 0 ;
463+ }
464+
465+ #define EMUL_I2C_DEFINE (inst ) \
466+ EMUL_DT_INST_DEFINE(inst, &emul_imager_init_i2c, NULL, NULL, &emul_imager_i2c_api, NULL);
467+
468+ DT_INST_FOREACH_STATUS_OKAY (EMUL_I2C_DEFINE )
0 commit comments