Skip to content

Commit 066931c

Browse files
committed
drivers: video: Update OV7670 to use generic ov767x functions
drivers: video: Update OV7670 to use generic ov767x functions Minimal changes to OV760 drive to use generic ov767x structures. - This includes changes to function names. - Includes changes to defines as necessary. - Deleted camera_id as no longer required Signed-off-by: Mike S <[email protected]>
1 parent 2ae56ea commit 066931c

File tree

1 file changed

+98
-72
lines changed

1 file changed

+98
-72
lines changed

drivers/video/ov7670.c

Lines changed: 98 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
/*
22
* Copyright 2024 NXP
3+
* Copyright 2021 Arduino SA
4+
* Copyright (c) 2025 Michael Smorto
35
*
46
* SPDX-License-Identifier: Apache-2.0
57
*/
@@ -16,10 +18,12 @@
1618
#include "video_ctrls.h"
1719
#include "video_device.h"
1820

19-
LOG_MODULE_REGISTER(video_ov7670, CONFIG_VIDEO_LOG_LEVEL);
21+
LOG_MODULE_REGISTER(video_ov767x, CONFIG_VIDEO_LOG_LEVEL);
2022

21-
struct ov7670_config {
23+
struct ov767x_config {
2224
struct i2c_dt_spec bus;
25+
uint32_t camera_model;
26+
const struct video_format_cap *fmts;
2327
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
2428
struct gpio_dt_spec reset;
2529
#endif
@@ -28,13 +32,13 @@ struct ov7670_config {
2832
#endif
2933
};
3034

31-
struct ov7670_ctrls {
35+
struct ov767x_ctrls {
3236
struct video_ctrl hflip;
3337
struct video_ctrl vflip;
3438
};
3539

36-
struct ov7670_data {
37-
struct ov7670_ctrls ctrls;
40+
struct ov767x_data {
41+
struct ov767x_ctrls ctrls;
3842
struct video_format fmt;
3943
};
4044

@@ -133,29 +137,32 @@ struct ov7670_data {
133137
#define OV7670_MVFP_HFLIP 0x20
134138
#define OV7670_MVFP_VFLIP 0x10
135139

136-
#define OV7670_VIDEO_FORMAT_CAP(width, height, format) \
140+
#define OV767X_MODEL_OV7670 7670
141+
#define OV767X_MODEL_OV7675 7675
142+
143+
#define OV767X_VIDEO_FORMAT_CAP(width, height, format) \
137144
{ \
138145
.pixelformat = (format), .width_min = (width), .width_max = (width), \
139146
.height_min = (height), .height_max = (height), .width_step = 0, .height_step = 0 \
140147
}
141148

142-
static const struct video_format_cap fmts[] = {
143-
OV7670_VIDEO_FORMAT_CAP(176, 144, VIDEO_PIX_FMT_RGB565), /* QCIF */
144-
OV7670_VIDEO_FORMAT_CAP(320, 240, VIDEO_PIX_FMT_RGB565), /* QVGA */
145-
OV7670_VIDEO_FORMAT_CAP(352, 288, VIDEO_PIX_FMT_RGB565), /* CIF */
146-
OV7670_VIDEO_FORMAT_CAP(640, 480, VIDEO_PIX_FMT_RGB565), /* VGA */
147-
OV7670_VIDEO_FORMAT_CAP(176, 144, VIDEO_PIX_FMT_YUYV), /* QCIF */
148-
OV7670_VIDEO_FORMAT_CAP(320, 240, VIDEO_PIX_FMT_YUYV), /* QVGA */
149-
OV7670_VIDEO_FORMAT_CAP(352, 288, VIDEO_PIX_FMT_YUYV), /* CIF */
150-
OV7670_VIDEO_FORMAT_CAP(640, 480, VIDEO_PIX_FMT_YUYV), /* VGA */
149+
static const struct video_format_cap ov7670_fmts[] = {
150+
OV767X_VIDEO_FORMAT_CAP(176, 144, VIDEO_PIX_FMT_RGB565), /* QCIF */
151+
OV767X_VIDEO_FORMAT_CAP(320, 240, VIDEO_PIX_FMT_RGB565), /* QVGA */
152+
OV767X_VIDEO_FORMAT_CAP(352, 288, VIDEO_PIX_FMT_RGB565), /* CIF */
153+
OV767X_VIDEO_FORMAT_CAP(640, 480, VIDEO_PIX_FMT_RGB565), /* VGA */
154+
OV767X_VIDEO_FORMAT_CAP(176, 144, VIDEO_PIX_FMT_YUYV), /* QCIF */
155+
OV767X_VIDEO_FORMAT_CAP(320, 240, VIDEO_PIX_FMT_YUYV), /* QVGA */
156+
OV767X_VIDEO_FORMAT_CAP(352, 288, VIDEO_PIX_FMT_YUYV), /* CIF */
157+
OV767X_VIDEO_FORMAT_CAP(640, 480, VIDEO_PIX_FMT_YUYV), /* VGA */
151158
{0}
152159
};
153160

154161
/*
155162
* This initialization table is based on the MCUX SDK driver for the OV7670.
156163
* Note that this table assumes the camera is fed a 6MHz XCLK signal
157164
*/
158-
static const struct video_reg8 ov7670_init_regtbl[] = {
165+
static const struct video_reg8 ov767x_init_regtbl[] = {
159166
{OV7670_MVFP, 0x00}, /* MVFP: Mirror/VFlip,Normal image */
160167

161168
/* configure the output timing */
@@ -354,16 +361,19 @@ static const struct video_reg8 ov7670_regs_vga[] = {
354361
{OV7670_SCALING_PCLK_DELAY, 0x02},
355362
};
356363

357-
static int ov7670_get_caps(const struct device *dev, struct video_caps *caps)
364+
static int ov767x_get_caps(const struct device *dev, struct video_caps *caps)
358365
{
359-
caps->format_caps = fmts;
366+
const struct ov767x_config *config = dev->config;
367+
368+
caps->format_caps = config->fmts;
360369
return 0;
361370
}
362371

372+
#if DT_HAS_COMPAT_STATUS_OKAY(ovti_ov7670)
363373
static int ov7670_set_fmt(const struct device *dev, struct video_format *fmt)
364374
{
365-
const struct ov7670_config *config = dev->config;
366-
struct ov7670_data *data = dev->data;
375+
const struct ov767x_config *config = dev->config;
376+
struct ov767x_data *data = dev->data;
367377
int ret = -ENOTSUP;
368378
uint8_t i = 0U;
369379

@@ -372,20 +382,13 @@ static int ov7670_set_fmt(const struct device *dev, struct video_format *fmt)
372382
return -ENOTSUP;
373383
}
374384

375-
if (!memcmp(&data->fmt, fmt, sizeof(data->fmt))) {
376-
/* nothing to do */
377-
return 0;
378-
}
379-
380-
memcpy(&data->fmt, fmt, sizeof(data->fmt));
381-
382385
/* Set output resolution */
383-
while (fmts[i].pixelformat) {
384-
if (fmts[i].width_min == fmt->width &&
385-
fmts[i].height_min == fmt->height &&
386-
fmts[i].pixelformat == fmt->pixelformat) {
386+
while (config->fmts[i].pixelformat) {
387+
if (config->fmts[i].width_min == fmt->width &&
388+
config->fmts[i].height_min == fmt->height &&
389+
config->fmts[i].pixelformat == fmt->pixelformat) {
387390
/* Set output format */
388-
switch (fmts[i].width_min) {
391+
switch (config->fmts[i].width_min) {
389392
case 176: /* QCIF */
390393
ret = video_write_cci_multiregs8(&config->bus, ov7670_regs_qcif,
391394
ARRAY_SIZE(ov7670_regs_qcif));
@@ -422,20 +425,40 @@ static int ov7670_set_fmt(const struct device *dev, struct video_format *fmt)
422425

423426
return 0;
424427
}
428+
#endif
425429

426-
static int ov7670_get_fmt(const struct device *dev, struct video_format *fmt)
430+
static int ov767x_set_fmt(const struct device *dev, struct video_format *fmt)
427431
{
428-
struct ov7670_data *data = dev->data;
432+
int ret;
433+
434+
if (fmt->pixelformat != VIDEO_PIX_FMT_RGB565 && fmt->pixelformat != VIDEO_PIX_FMT_YUYV) {
435+
LOG_ERR("Only RGB565 and YUYV supported!");
436+
return -ENOTSUP;
437+
}
438+
439+
#if DT_HAS_COMPAT_STATUS_OKAY(ovti_ov7670)
440+
ret = ov7670_set_fmt(dev, fmt);
441+
if (ret < 0) {
442+
return ret;
443+
}
444+
#endif
445+
446+
return 0;
447+
}
448+
449+
static int ov767x_get_fmt(const struct device *dev, struct video_format *fmt)
450+
{
451+
struct ov767x_data *data = dev->data;
429452

430453
memcpy(fmt, &data->fmt, sizeof(data->fmt));
431454
return 0;
432455
}
433456

434-
static int ov7670_init_controls(const struct device *dev)
457+
static int ov767x_init_controls(const struct device *dev)
435458
{
436459
int ret;
437-
struct ov7670_data *drv_data = dev->data;
438-
struct ov7670_ctrls *ctrls = &drv_data->ctrls;
460+
struct ov767x_data *drv_data = dev->data;
461+
struct ov767x_ctrls *ctrls = &drv_data->ctrls;
439462

440463
ret = video_init_ctrl(&ctrls->hflip, dev, VIDEO_CID_HFLIP,
441464
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 0});
@@ -447,9 +470,9 @@ static int ov7670_init_controls(const struct device *dev)
447470
(struct video_ctrl_range){.min = 0, .max = 1, .step = 1, .def = 0});
448471
}
449472

450-
static int ov7670_init(const struct device *dev)
473+
static int ov767x_init(const struct device *dev)
451474
{
452-
const struct ov7670_config *config = dev->config;
475+
const struct ov767x_config *config = dev->config;
453476
int ret;
454477
uint8_t pid;
455478
struct video_format fmt = {
@@ -463,7 +486,7 @@ static int ov7670_init(const struct device *dev)
463486
return -ENODEV;
464487
}
465488

466-
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(pwdn_gpios)
489+
#if DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(ovti_ov7670, pwdn_gpios)
467490
/* Power up camera module */
468491
if (config->pwdn.port != NULL) {
469492
if (!gpio_is_ready_dt(&config->pwdn)) {
@@ -476,7 +499,8 @@ static int ov7670_init(const struct device *dev)
476499
}
477500
}
478501
#endif
479-
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
502+
503+
#if DT_ANY_COMPAT_HAS_PROP_STATUS_OKAY(ovti_ov7670, reset_gpios)
480504
/* Reset camera module */
481505
if (config->reset.port != NULL) {
482506
if (!gpio_is_ready_dt(&config->reset)) {
@@ -528,35 +552,32 @@ static int ov7670_init(const struct device *dev)
528552
}
529553
/* Delay after reset */
530554
k_msleep(5);
531-
532-
ret = ov7670_set_fmt(dev, &fmt);
533-
555+
ret = ov767x_set_fmt(dev, &fmt);
534556
if (ret < 0) {
535557
return ret;
536558
}
537559

538560
/* Write initialization values to OV7670 */
539-
ret = video_write_cci_multiregs8(&config->bus, ov7670_init_regtbl,
540-
ARRAY_SIZE(ov7670_init_regtbl));
541-
561+
ret = video_write_cci_multiregs8(&config->bus, ov767x_init_regtbl,
562+
ARRAY_SIZE(ov767x_init_regtbl));
542563
if (ret < 0) {
543564
return ret;
544565
}
545566

546567
/* Initialize controls */
547-
return ov7670_init_controls(dev);
568+
return ov767x_init_controls(dev);
548569
}
549570

550-
static int ov7670_set_stream(const struct device *dev, bool enable, enum video_buf_type type)
571+
static int ov767x_set_stream(const struct device *dev, bool enable, enum video_buf_type type)
551572
{
552573
return 0;
553574
}
554575

555-
static int ov7670_set_ctrl(const struct device *dev, uint32_t id)
576+
static int ov767x_set_ctrl(const struct device *dev, uint32_t id)
556577
{
557-
const struct ov7670_config *config = dev->config;
558-
struct ov7670_data *drv_data = dev->data;
559-
struct ov7670_ctrls *ctrls = &drv_data->ctrls;
578+
const struct ov767x_config *config = dev->config;
579+
struct ov767x_data *drv_data = dev->data;
580+
struct ov767x_ctrls *ctrls = &drv_data->ctrls;
560581

561582
switch (id) {
562583
case VIDEO_CID_HFLIP:
@@ -570,36 +591,41 @@ static int ov7670_set_ctrl(const struct device *dev, uint32_t id)
570591
}
571592
}
572593

573-
static DEVICE_API(video, ov7670_api) = {
574-
.set_format = ov7670_set_fmt,
575-
.get_format = ov7670_get_fmt,
576-
.get_caps = ov7670_get_caps,
577-
.set_stream = ov7670_set_stream,
578-
.set_ctrl = ov7670_set_ctrl,
594+
static DEVICE_API(video, ov767x_api) = {
595+
.set_format = ov767x_set_fmt,
596+
.get_format = ov767x_get_fmt,
597+
.get_caps = ov767x_get_caps,
598+
.set_stream = ov767x_set_stream,
599+
.set_ctrl = ov767x_set_ctrl,
579600
};
580601

581602
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(reset_gpios)
582-
#define OV7670_RESET_GPIO(inst) .reset = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, {}),
603+
#define OV767X_RESET_GPIO(inst) .reset = GPIO_DT_SPEC_INST_GET_OR(inst, reset_gpios, {}),
583604
#else
584-
#define OV7670_RESET_GPIO(inst)
605+
#define OV767X_RESET_GPIO(inst)
585606
#endif
586607

587608
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY(pwdn_gpios)
588-
#define OV7670_PWDN_GPIO(inst) .pwdn = GPIO_DT_SPEC_INST_GET_OR(inst, pwdn_gpios, {}),
609+
#define OV767X_PWDN_GPIO(inst) .pwdn = GPIO_DT_SPEC_INST_GET_OR(inst, pwdn_gpios, {}),
589610
#else
590-
#define OV7670_PWDN_GPIO(inst)
611+
#define OV767X_PWDN_GPIO(inst)
591612
#endif
592613

593-
#define OV7670_INIT(inst) \
594-
const struct ov7670_config ov7670_config_##inst = {.bus = I2C_DT_SPEC_INST_GET(inst), \
595-
OV7670_RESET_GPIO(inst) \
596-
OV7670_PWDN_GPIO(inst)}; \
614+
#define OV767X_INIT(inst, id) \
615+
static const struct ov767x_config ov##id##_config##inst = { \
616+
.bus = I2C_DT_SPEC_INST_GET(inst), \
617+
.camera_model = id, \
618+
.fmts = ov##id##_fmts, \
619+
OV767X_RESET_GPIO(inst) OV767X_PWDN_GPIO(inst)}; \
597620
\
598-
struct ov7670_data ov7670_data_##inst; \
621+
static struct ov767x_data ov##id##_data##inst; \
599622
\
600-
DEVICE_DT_INST_DEFINE(inst, ov7670_init, NULL, &ov7670_data_##inst, &ov7670_config_##inst, \
601-
POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, &ov7670_api); \
623+
DEVICE_DT_INST_DEFINE(inst, ov767x_init, NULL, &ov##id##_data##inst, \
624+
&ov##id##_config##inst, POST_KERNEL, CONFIG_VIDEO_INIT_PRIORITY, \
625+
&ov767x_api); \
602626
\
603-
VIDEO_DEVICE_DEFINE(ov7670_##inst, DEVICE_DT_INST_GET(inst), NULL);
627+
VIDEO_DEVICE_DEFINE(ov##id##inst, DEVICE_DT_INST_GET(inst), NULL);
604628

605-
DT_INST_FOREACH_STATUS_OKAY(OV7670_INIT)
629+
#undef DT_DRV_COMPAT
630+
#define DT_DRV_COMPAT ovti_ov7670
631+
DT_INST_FOREACH_STATUS_OKAY_VARGS(OV767X_INIT, 7670)

0 commit comments

Comments
 (0)