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 ,
@@ -344,12 +337,13 @@ static int emul_imager_init_controls(const struct device *dev)
344337
345338int emul_imager_init (const struct device * dev )
346339{
340+ const struct emul_imager_config * cfg = dev -> config ;
347341 struct video_format fmt ;
348342 uint8_t sensor_id ;
349343 int ret ;
350344
351- if (/* !i2c_is_ready_dt(&cfg->i2c) */ false ) {
352- /* LOG_ERR("Bus %s is not ready", cfg->i2c.bus->name); */
345+ if (!i2c_is_ready_dt (& cfg -> i2c )) {
346+ LOG_ERR ("Bus %s is not ready" , cfg -> i2c .bus -> name );
353347 return - ENODEV ;
354348 }
355349
@@ -384,7 +378,7 @@ int emul_imager_init(const struct device *dev)
384378 static struct emul_imager_data emul_imager_data_##inst; \
385379 \
386380 static const struct emul_imager_config emul_imager_cfg_##inst = { \
387- .i2c = /* I2C_DT_SPEC_INST_GET(inst) */ { 0 }, \
381+ .i2c = I2C_DT_SPEC_INST_GET(inst), \
388382 }; \
389383 \
390384 DEVICE_DT_INST_DEFINE(inst, &emul_imager_init, NULL, &emul_imager_data_##inst, \
@@ -394,3 +388,50 @@ int emul_imager_init(const struct device *dev)
394388 VIDEO_DEVICE_DEFINE(emul_imager_##inst, DEVICE_DT_INST_GET(inst), NULL);
395389
396390DT_INST_FOREACH_STATUS_OKAY (EMUL_IMAGER_DEFINE )
391+
392+ /* Simulated I2C bus */
393+
394+ static int emul_imager_transfer_i2c (const struct emul * target , struct i2c_msg msgs [], int num_msgs ,
395+ int addr )
396+ {
397+ static uint8_t fake_regs [UINT8_MAX ] = {
398+ [EMUL_IMAGER_REG_SENSOR_ID ] = EMUL_IMAGER_SENSOR_ID ,
399+ };
400+
401+ if (num_msgs == 0 ) {
402+ CODE_UNREACHABLE ;
403+ } else if (num_msgs == 1 &&
404+ msgs [0 ].len == 2 && (msgs [0 ].flags & I2C_MSG_READ ) == 0 ) {
405+ /* Register write */
406+ fake_regs [msgs [0 ].buf [0 ]] = msgs [0 ].buf [1 ];
407+ } else if (num_msgs == 2 &&
408+ msgs [0 ].len == 1 && (msgs [0 ].flags & I2C_MSG_READ ) == 0 &&
409+ msgs [1 ].len == 1 && (msgs [1 ].flags & I2C_MSG_READ ) == 0 ) {
410+ /* Register write */
411+ fake_regs [msgs [0 ].buf [0 ]] = msgs [1 ].buf [0 ];
412+ } else if (num_msgs == 2 &&
413+ msgs [0 ].len == 1 && (msgs [0 ].flags & I2C_MSG_READ ) == 0 &&
414+ msgs [1 ].len == 1 && (msgs [1 ].flags & I2C_MSG_READ ) != 0 ) {
415+ /* Register read */
416+ msgs [1 ].buf [0 ] = fake_regs [msgs [0 ].buf [0 ]];
417+ } else {
418+ LOG_ERR ("Unsupported I2C operation of %u messages" , num_msgs );
419+ return - EIO ;
420+ }
421+
422+ return 0 ;
423+ }
424+
425+ static const struct i2c_emul_api emul_imager_i2c_api = {
426+ .transfer = emul_imager_transfer_i2c ,
427+ };
428+
429+ static int emul_imager_init_i2c (const struct emul * target , const struct device * dev )
430+ {
431+ return 0 ;
432+ }
433+
434+ #define EMUL_I2C_DEFINE (inst ) \
435+ EMUL_DT_INST_DEFINE(inst, &emul_imager_init_i2c, NULL, NULL, &emul_imager_i2c_api, NULL);
436+
437+ DT_INST_FOREACH_STATUS_OKAY (EMUL_I2C_DEFINE )
0 commit comments