15
15
#include <zephyr/drivers/video.h>
16
16
#include <zephyr/drivers/video-controls.h>
17
17
#include <zephyr/drivers/i2c.h>
18
+ #include <zephyr/drivers/i2c_emul.h>
18
19
#include <zephyr/logging/log.h>
19
20
20
21
LOG_MODULE_REGISTER (video_emul_imager , CONFIG_VIDEO_LOG_LEVEL );
21
22
22
- #define EMUL_IMAGER_REG_SENSOR_ID 0x0000
23
+ #define EMUL_IMAGER_REG_SENSOR_ID 0x00
23
24
#define EMUL_IMAGER_SENSOR_ID 0x99
24
- #define EMUL_IMAGER_REG_CTRL 0x0001
25
- #define EMUL_IMAGER_REG_INIT1 0x0002
26
- #define EMUL_IMAGER_REG_INIT2 0x0003
27
- #define EMUL_IMAGER_REG_TIMING1 0x0004
28
- #define EMUL_IMAGER_REG_TIMING2 0x0005
29
- #define EMUL_IMAGER_REG_TIMING3 0x0006
30
- #define EMUL_IMAGER_REG_CUSTOM 0x0007
31
- #define EMUL_IMAGER_REG_FORMAT 0x000a
25
+ #define EMUL_IMAGER_REG_CTRL 0x01
26
+ #define EMUL_IMAGER_REG_INIT1 0x02
27
+ #define EMUL_IMAGER_REG_INIT2 0x03
28
+ #define EMUL_IMAGER_REG_TIMING1 0x04
29
+ #define EMUL_IMAGER_REG_TIMING2 0x05
30
+ #define EMUL_IMAGER_REG_TIMING3 0x06
31
+ #define EMUL_IMAGER_REG_CUSTOM 0x07
32
+ #define EMUL_IMAGER_REG_FORMAT 0x0a
32
33
#define EMUL_IMAGER_PATTERN_OFF 0x00
33
34
#define EMUL_IMAGER_PATTERN_BARS1 0x01
34
35
#define EMUL_IMAGER_PATTERN_BARS2 0x02
35
36
36
37
/* Custom control that is just an I2C write for example and test purpose */
37
38
#define EMUL_IMAGER_CID_CUSTOM (VIDEO_CID_PRIVATE_BASE + 0x01)
38
39
39
- /* Emulated register bank */
40
- uint8_t emul_imager_fake_regs [10 ];
41
-
42
40
enum emul_imager_fmt_id {
43
41
RGB565_320x240 ,
44
42
YUYV_320x240 ,
@@ -152,21 +150,15 @@ static const struct video_format_cap fmts[] = {
152
150
/* Emulated I2C register interface, to replace with actual I2C calls for real hardware */
153
151
static int emul_imager_read_reg (const struct device * const dev , uint8_t reg_addr , uint8_t * value )
154
152
{
155
- LOG_DBG ("Placeholder for I2C read from 0x%02x" , reg_addr );
156
- switch (reg_addr ) {
157
- case EMUL_IMAGER_REG_SENSOR_ID :
158
- * value = EMUL_IMAGER_SENSOR_ID ;
159
- break ;
160
- default :
161
- * value = emul_imager_fake_regs [reg_addr ];
162
- }
163
- return 0 ;
153
+ const struct emul_imager_config * cfg = dev -> config ;
154
+
155
+ return i2c_write_read_dt (& cfg -> i2c , & reg_addr , 1 , value , 1 );
164
156
}
165
157
166
158
/* Helper to read a full integer directly from a register */
167
159
static int emul_imager_read_int (const struct device * const dev , uint8_t reg_addr , int * value )
168
160
{
169
- uint8_t val8 ;
161
+ uint8_t val8 = 0 ;
170
162
int ret ;
171
163
172
164
ret = emul_imager_read_reg (dev , reg_addr , & val8 );
@@ -177,9 +169,10 @@ static int emul_imager_read_int(const struct device *const dev, uint8_t reg_addr
177
169
/* Some sensors will need reg8 or reg16 variants. */
178
170
static int emul_imager_write_reg (const struct device * const dev , uint8_t reg_addr , uint8_t value )
179
171
{
180
- LOG_DBG ("Placeholder for I2C write 0x%08x to 0x%02x" , value , reg_addr );
181
- emul_imager_fake_regs [reg_addr ] = value ;
182
- return 0 ;
172
+ const struct emul_imager_config * cfg = dev -> config ;
173
+ uint8_t buf_w [] = {reg_addr , value };
174
+
175
+ return i2c_write_dt (& cfg -> i2c , buf_w , 2 );
183
176
}
184
177
185
178
static int emul_imager_write_multi (const struct device * const dev ,
@@ -383,12 +376,13 @@ static DEVICE_API(video, emul_imager_driver_api) = {
383
376
384
377
int emul_imager_init (const struct device * dev )
385
378
{
379
+ const struct emul_imager_config * cfg = dev -> config ;
386
380
struct video_format fmt ;
387
381
uint8_t sensor_id ;
388
382
int ret ;
389
383
390
- if (/* !i2c_is_ready_dt(&cfg->i2c) */ false ) {
391
- /* LOG_ERR("Bus %s is not ready", cfg->i2c.bus->name); */
384
+ if (!i2c_is_ready_dt (& cfg -> i2c )) {
385
+ LOG_ERR ("Bus %s is not ready" , cfg -> i2c .bus -> name );
392
386
return - ENODEV ;
393
387
}
394
388
@@ -422,11 +416,58 @@ int emul_imager_init(const struct device *dev)
422
416
static struct emul_imager_data emul_imager_data_##inst; \
423
417
\
424
418
static const struct emul_imager_config emul_imager_cfg_##inst = { \
425
- .i2c = /* I2C_DT_SPEC_INST_GET(inst) */ { 0 }, \
419
+ .i2c = I2C_DT_SPEC_INST_GET(inst), \
426
420
}; \
427
421
\
428
422
DEVICE_DT_INST_DEFINE(inst, &emul_imager_init, NULL, &emul_imager_data_##inst, \
429
423
&emul_imager_cfg_##inst, POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, \
430
424
&emul_imager_driver_api);
431
425
432
426
DT_INST_FOREACH_STATUS_OKAY (EMUL_IMAGER_DEFINE )
427
+
428
+ /* Simulated I2C bus */
429
+
430
+ static int emul_imager_transfer_i2c (const struct emul * target , struct i2c_msg msgs [], int num_msgs ,
431
+ int addr )
432
+ {
433
+ static uint8_t fake_regs [10 ] = {
434
+ [EMUL_IMAGER_REG_SENSOR_ID ] = EMUL_IMAGER_SENSOR_ID ,
435
+ };
436
+
437
+ if (num_msgs == 0 ) {
438
+ CODE_UNREACHABLE ;
439
+ } else if (num_msgs == 1 &&
440
+ msgs [0 ].len == 2 && (msgs [0 ].flags & I2C_MSG_READ ) == 0 ) {
441
+ /* Register write */
442
+ fake_regs [msgs [0 ].buf [0 ]] = msgs [0 ].buf [1 ];
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 write */
447
+ fake_regs [msgs [0 ].buf [0 ]] = msgs [1 ].buf [0 ];
448
+ } else if (num_msgs == 2 &&
449
+ msgs [0 ].len == 1 && (msgs [0 ].flags & I2C_MSG_READ ) == 0 &&
450
+ msgs [1 ].len == 1 && (msgs [1 ].flags & I2C_MSG_READ ) != 0 ) {
451
+ /* Register read */
452
+ msgs [1 ].buf [0 ] = fake_regs [msgs [0 ].buf [0 ]];
453
+ } else {
454
+ LOG_ERR ("Unsupported I2C operation of %u messages" , num_msgs );
455
+ return - EIO ;
456
+ }
457
+
458
+ return 0 ;
459
+ }
460
+
461
+ static const struct i2c_emul_api emul_imager_i2c_api = {
462
+ .transfer = emul_imager_transfer_i2c ,
463
+ };
464
+
465
+ static int emul_imager_init_i2c (const struct emul * target , const struct device * dev )
466
+ {
467
+ return 0 ;
468
+ }
469
+
470
+ #define EMUL_I2C_DEFINE (inst ) \
471
+ EMUL_DT_INST_DEFINE(inst, &emul_imager_init_i2c, NULL, NULL, &emul_imager_i2c_api, NULL);
472
+
473
+ DT_INST_FOREACH_STATUS_OKAY (EMUL_I2C_DEFINE )
0 commit comments