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
#include "video_ctrls.h"
21
22
#include "video_device.h"
22
23
23
24
LOG_MODULE_REGISTER (video_emul_imager , CONFIG_VIDEO_LOG_LEVEL );
24
25
25
- #define EMUL_IMAGER_REG_SENSOR_ID 0x0000
26
+ #define EMUL_IMAGER_REG_SENSOR_ID 0x00
26
27
#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
35
36
#define EMUL_IMAGER_PATTERN_OFF 0x00
36
37
#define EMUL_IMAGER_PATTERN_BARS1 0x01
37
38
#define EMUL_IMAGER_PATTERN_BARS2 0x02
38
39
39
40
/* Custom control that is just an I2C write for example and test purpose */
40
41
#define EMUL_IMAGER_CID_CUSTOM (VIDEO_CID_PRIVATE_BASE + 0x01)
41
42
42
- /* Emulated register bank */
43
- uint8_t emul_imager_fake_regs [10 ];
44
-
45
43
enum emul_imager_fmt_id {
46
44
RGB565_320x240 ,
47
45
YUYV_320x240 ,
@@ -86,10 +84,10 @@ static const struct emul_imager_reg emul_imager_init_regs[] = {
86
84
{EMUL_IMAGER_REG_INIT1 , 0x10 },
87
85
{EMUL_IMAGER_REG_INIT2 , 0x00 },
88
86
/* 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 },
93
91
{0 },
94
92
};
95
93
static const struct emul_imager_reg emul_imager_rgb565 [] = {
@@ -160,23 +158,18 @@ static const struct video_format_cap fmts[] = {
160
158
/* Emulated I2C register interface, to replace with actual I2C calls for real hardware */
161
159
static int emul_imager_read_reg (const struct device * const dev , uint8_t reg_addr , uint8_t * value )
162
160
{
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 );
172
164
}
173
165
174
166
/* Some sensors will need reg8 or reg16 variants. */
175
167
static int emul_imager_write_reg (const struct device * const dev , uint8_t reg_addr , uint8_t value )
176
168
{
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 );
180
173
}
181
174
182
175
static int emul_imager_write_multi (const struct device * const dev ,
@@ -375,12 +368,13 @@ static int emul_imager_init_controls(const struct device *dev)
375
368
376
369
int emul_imager_init (const struct device * dev )
377
370
{
371
+ const struct emul_imager_config * cfg = dev -> config ;
378
372
struct video_format fmt ;
379
373
uint8_t sensor_id ;
380
374
int ret ;
381
375
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 );
384
378
return - ENODEV ;
385
379
}
386
380
@@ -415,7 +409,7 @@ int emul_imager_init(const struct device *dev)
415
409
static struct emul_imager_data emul_imager_data_##inst; \
416
410
\
417
411
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), \
419
413
}; \
420
414
\
421
415
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)
425
419
VIDEO_DEVICE_DEFINE(emul_imager_##inst, DEVICE_DT_INST_GET(inst), NULL);
426
420
427
421
DT_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