Skip to content

Commit 75927c0

Browse files
committed
drivers: video Add Restructure of set_fmt function
drivers: video Add Restructure of set_fmt function set_fmt split to 0v7670_set_fmt & 0v7675_set_fmt. Added separate RGB565 settings for cameras based on OpenMv Signed-off-by: Mike S <[email protected]>
1 parent 9f81952 commit 75927c0

File tree

1 file changed

+163
-66
lines changed

1 file changed

+163
-66
lines changed

drivers/video/ov767x.c

Lines changed: 163 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/*
22
* Copyright 2024 NXP
33
* Copyright 2021 Arduino SA
4+
* Copyright (c) 2013-2021 Ibrahim Abdelkader <[email protected]>
5+
* Copyright (c) 2013-2021 Kwabena W. Agyeman <[email protected]>
46
* Copyright (c) 2025 Michael Smorto
57
*
68
* SPDX-License-Identifier: Apache-2.0
@@ -134,15 +136,16 @@ struct ov767x_data {
134136
#define OV7670_HAECC5 0xA8
135137
#define OV7670_HAECC6 0xA9
136138

137-
/* Addition defines for OV7675 */
138-
#define OV7675_RGB444 0x8C /* REG444 */
139-
#define OV7675_COM3_DCW_EN 0x04 /* DCW enable */
140-
#define OV7670_COM1 0x04 /*Com Cntrl1 */
141-
#define OV7675_COM7_RGB_FMT 0x04 /* Output format RGB */
142-
#define OV7675_COM13_GAMMA_EN 0x80 /* Gamma enable */
143-
#define OV7675_COM13_UVSAT_AUTO 0x40 /* UV saturation level - UV auto adjustment. */
144-
#define OV7675_COM15_OUT_00_FF 0xC0 /* Output data range 00 to FF */
145-
#define OV7675_COM15_FMT_RGB565 0x10 /* Normal RGB 565 output */
139+
/* Addition defines to support OV7675 */
140+
#define OV7670_RGB444 0x8C /* REG444 */
141+
#define OV7675_COM3_DCW_EN 0x04 /* DCW enable */
142+
#define OV7670_COM1 0x04 /*Com Cntrl1 */
143+
#define OV7675_COM7_RGB_FMT 0x04 /* Output format RGB */
144+
#define OV7675_COM13_GAMMA_EN 0x80 /* Gamma enable */
145+
#define OV7675_COM13_UVSAT_AUTO 0x40 /* UV saturation level - UV auto adjustment. */
146+
#define OV7675_COM15_OUT_00_FF 0xC0 /* Output data range 00 to FF */
147+
#define OV7675_COM15_FMT_RGB_NORMAL 0x00 /* Normal RGB normal output */
148+
#define OV7675_COM15_FMT_RGB565 0x10 /* Normal RGB 565 output */
146149

147150
/* OV7670 definitions */
148151
#define OV7670_PROD_ID 0x76
@@ -342,25 +345,10 @@ static const struct video_reg8 ov767x_init_regtbl[] = {
342345
{0xb8, 0x0a},
343346
};
344347

345-
static const struct video_reg8 ov767x_rgb565_regs[] = {
346-
{OV7670_COM7, OV7675_COM7_RGB_FMT}, /* Selects RGB mode */
347-
{OV7675_RGB444, 0x00}, /* No RGB444 please */
348-
{OV7670_COM1, 0x00}, /* CCIR601 */
349-
{OV7670_COM15, OV7675_COM15_OUT_00_FF | OV7675_COM15_FMT_RGB565},
350-
{OV7670_COM9, 0x38}, /* 16x gain ceiling; 0x8 is reserved bit */
351-
{0x4f, 0xb3}, /* "matrix coefficient 1" */
352-
{0x50, 0xb3}, /* "matrix coefficient 2" */
353-
{0x51, 0x00}, /* "matrix Coefficient 3" */
354-
{0x52, 0x3d}, /* "matrix coefficient 4" */
355-
{0x53, 0xa7}, /* "matrix coefficient 5" */
356-
{0x54, 0xe4}, /* "matrix coefficient 6" */
357-
{OV7670_COM13, OV7675_COM13_GAMMA_EN | OV7675_COM13_UVSAT_AUTO},
358-
};
359-
360348
/* TODO: These registers probably need to be fixed too. */
361349
static const struct video_reg8 ov767x_yuv422_regs[] = {
362350
{OV7670_COM7, 0x00}, /* Selects YUV mode */
363-
{OV7675_RGB444, 0x00}, /* No RGB444 please */
351+
{OV7670_RGB444, 0x00}, /* No RGB444 please */
364352
{OV7670_COM1, 0x00}, /* CCIR601 */
365353
{OV7670_COM15, OV7675_COM15_OUT_00_FF},
366354
{OV7670_COM9, 0x48}, /* 32x gain ceiling; 0x8 is reserved bit */
@@ -373,6 +361,22 @@ static const struct video_reg8 ov767x_yuv422_regs[] = {
373361
{OV7670_COM13, OV7675_COM13_GAMMA_EN | OV7675_COM13_UVSAT_AUTO},
374362
};
375363

364+
#if DT_HAS_COMPAT_STATUS_OKAY(ovti_ov7670)
365+
static const struct video_reg8 ov7670_rgb565_regs[] = {
366+
{OV7670_COM7, OV7675_COM7_RGB_FMT}, /* Selects RGB mode */
367+
{OV7670_RGB444, 0x00}, /* No RGB444 please */
368+
{OV7670_COM1, 0x00}, /* CCIR601 */
369+
{OV7670_COM15, OV7675_COM15_OUT_00_FF | OV7675_COM15_FMT_RGB565},
370+
{OV7670_COM9, 0x6a}, /* 16x gain ceiling; 0x8 is reserved bit */
371+
{0x4f, 0xb3}, /* "matrix coefficient 1" */
372+
{0x50, 0xb3}, /* "matrix coefficient 2" */
373+
{0x51, 0x00}, /* "matrix Coefficient 3" */
374+
{0x52, 0x3d}, /* "matrix coefficient 4" */
375+
{0x53, 0xa7}, /* "matrix coefficient 5" */
376+
{0x54, 0xe4}, /* "matrix coefficient 6" */
377+
{OV7670_COM13, OV7675_COM13_UVSAT_AUTO},
378+
};
379+
376380
/* Resolution settings for camera, based on those present in MCUX SDK */
377381
static const struct video_reg8 ov7670_regs_qcif[] = {
378382
{OV7670_COM7, 0x2c},
@@ -417,6 +421,23 @@ static const struct video_reg8 ov7670_regs_vga[] = {
417421
{OV7670_SCALING_PCLK_DIV, 0xf0},
418422
{OV7670_SCALING_PCLK_DELAY, 0x02},
419423
};
424+
#endif
425+
426+
#if DT_HAS_COMPAT_STATUS_OKAY(ovti_ov7675)
427+
static const struct video_reg8 ov7675_rgb565_regs[] = {
428+
{OV7670_COM7, OV7675_COM7_RGB_FMT}, /* Selects RGB mode */
429+
{OV7670_RGB444, 0x00}, /* No RGB444 please */
430+
{OV7670_COM1, 0x00}, /* CCIR601 */
431+
{OV7670_COM15, OV7675_COM15_OUT_00_FF | OV7675_COM15_FMT_RGB565},
432+
{OV7670_COM9, 0x38}, /* 16x gain ceiling; 0x8 is reserved bit */
433+
{0x4f, 0xb3}, /* "matrix coefficient 1" */
434+
{0x50, 0xb3}, /* "matrix coefficient 2" */
435+
{0x51, 0x00}, /* "matrix Coefficient 3" */
436+
{0x52, 0x3d}, /* "matrix coefficient 4" */
437+
{0x53, 0xa7}, /* "matrix coefficient 5" */
438+
{0x54, 0xe4}, /* "matrix coefficient 6" */
439+
{OV7670_COM13, OV7675_COM13_GAMMA_EN | OV7675_COM13_UVSAT_AUTO},
440+
};
420441

421442
static const struct video_reg8 ov7675_regs_vga[] = {
422443
{OV7670_COM3, 0x00}, {OV7670_COM14, 0x00}, {0x72, 0x11}, /* downsample by 4 */
@@ -428,8 +449,8 @@ static const struct video_reg8 ov7675_regs_vga[] = {
428449
static const struct video_reg8 ov7675_regs_qvga[] = {
429450
{OV7670_COM3, OV7675_COM3_DCW_EN},
430451
{OV7670_COM14, 0x11}, /* Divide by 2 */
431-
{0x72, 0x22}, /* This has no effect on OV7675 */
432-
{0x73, 0xf2}, /* This has no effect on OV7675 */
452+
{0x72, 0x22},
453+
{0x73, 0xf2},
433454
{OV7670_HSTART, 0x15},
434455
{OV7670_HSTOP, 0x03},
435456
{OV7670_HREF, 0xC0},
@@ -441,15 +462,16 @@ static const struct video_reg8 ov7675_regs_qvga[] = {
441462
static const struct video_reg8 ov7675_regs_qqvga[] = {
442463
{OV7670_COM3, OV7675_COM3_DCW_EN},
443464
{OV7670_COM14, 0x11}, /* Divide by 2 */
444-
{0x72, 0x22}, /* This has no effect on OV7675*/
445-
{0x73, 0xf2}, /* This has no effect on OV7675*/
465+
{0x72, 0x22},
466+
{0x73, 0xf2},
446467
{OV7670_HSTART, 0x16},
447468
{OV7670_HSTOP, 0x04},
448469
{OV7670_HREF, 0xa4},
449470
{OV7670_VSTRT, 0x22},
450471
{OV7670_VSTOP, 0x7a},
451472
{OV7670_VREF, 0xfa},
452473
};
474+
#endif
453475

454476
static int ov767x_get_caps(const struct device *dev, struct video_caps *caps)
455477
{
@@ -466,9 +488,26 @@ static int ov767x_set_fmt(const struct device *dev, struct video_format *fmt)
466488
int ret = -ENOTSUP;
467489
uint8_t i = 0U;
468490

469-
if (fmt->pixelformat != VIDEO_PIX_FMT_RGB565 && fmt->pixelformat != VIDEO_PIX_FMT_YUYV) {
470-
LOG_ERR("Only RGB565 and YUYV supported!");
471-
return -ENOTSUP;
491+
if (!memcmp(&data->fmt, fmt, sizeof(data->fmt))) {
492+
/* nothing to do */
493+
return 0;
494+
}
495+
496+
/* Set RGB Format */
497+
if (fmt->pixelformat == VIDEO_PIX_FMT_RGB565) {
498+
ret = video_write_cci_multiregs8(&config->bus, ov7670_rgb565_regs,
499+
ARRAY_SIZE(ov7670_rgb565_regs));
500+
} else if (fmt->pixelformat == VIDEO_PIX_FMT_YUYV) {
501+
ret = video_write_cci_multiregs8(&config->bus, ov767x_yuv422_regs,
502+
ARRAY_SIZE(ov767x_yuv422_regs));
503+
} else {
504+
LOG_ERR("Image format not supported");
505+
ret = -ENOTSUP;
506+
}
507+
508+
if (ret < 0) {
509+
LOG_ERR("Format not set!");
510+
return ret;
472511
}
473512

474513
if (!memcmp(&data->fmt, fmt, sizeof(data->fmt))) {
@@ -535,51 +574,107 @@ static int ov767x_set_fmt(const struct device *dev, struct video_format *fmt)
535574
i++;
536575
}
537576
}
577+
if (ret < 0) {
578+
LOG_ERR("Resolution not supported!");
579+
return ret;
580+
}
538581

539-
if (config->camera_model == OV767X_MODEL_OV7675) {
540-
while (config->fmts[i].pixelformat) {
541-
if (config->fmts[i].width_min == fmt->width &&
542-
config->fmts[i].height_min == fmt->height &&
543-
config->fmts[i].pixelformat == fmt->pixelformat) {
544-
/* Set output format */
545-
switch (config->fmts[i].width_min) {
546-
case 160: /* QQVGA */
547-
ret = video_write_cci_multiregs8(
548-
&config->bus, ov7675_regs_qqvga,
549-
ARRAY_SIZE(ov7675_regs_qqvga));
550-
break;
551-
case 320: /* QVGA */
552-
ret = video_write_cci_multiregs8(
553-
&config->bus, ov7675_regs_qvga,
554-
ARRAY_SIZE(ov7675_regs_qvga));
555-
break;
556-
case 640: /* VGA */
557-
ret = video_write_cci_multiregs8(
558-
&config->bus, ov7675_regs_vga,
559-
ARRAY_SIZE(ov7675_regs_vga));
560-
break;
561-
default: /* QVGA */
562-
ret = video_write_cci_multiregs8(
563-
&config->bus, ov7675_regs_qvga,
564-
ARRAY_SIZE(ov7675_regs_qvga));
565-
break;
566-
}
567-
if (ret < 0) {
568-
LOG_ERR("Resolution not set!");
569-
return ret;
570-
}
582+
return 0;
583+
}
584+
#endif
585+
#if DT_HAS_COMPAT_STATUS_OKAY(ovti_ov7675)
586+
static int ov7675_set_fmt(const struct device *dev, struct video_format *fmt)
587+
{
588+
const struct ov767x_config *config = dev->config;
589+
struct ov767x_data *data = dev->data;
590+
int ret = -ENOTSUP;
591+
uint8_t i = 0U;
592+
593+
if (!memcmp(&data->fmt, fmt, sizeof(data->fmt))) {
594+
/* nothing to do */
595+
return 0;
596+
}
597+
598+
/* Set RGB Format */
599+
if (fmt->pixelformat == VIDEO_PIX_FMT_RGB565) {
600+
ret = video_write_cci_multiregs8(&config->bus, ov7675_rgb565_regs,
601+
ARRAY_SIZE(ov7675_rgb565_regs));
602+
} else if (fmt->pixelformat == VIDEO_PIX_FMT_YUYV) {
603+
ret = video_write_cci_multiregs8(&config->bus, ov767x_yuv422_regs,
604+
ARRAY_SIZE(ov767x_yuv422_regs));
605+
} else {
606+
LOG_ERR("Image format not supported");
607+
ret = -ENOTSUP;
608+
}
609+
610+
if (ret < 0) {
611+
LOG_ERR("Format not set!");
612+
return ret;
613+
}
614+
615+
while (config->fmts[i].pixelformat) {
616+
if (config->fmts[i].width_min == fmt->width &&
617+
config->fmts[i].height_min == fmt->height &&
618+
config->fmts[i].pixelformat == fmt->pixelformat) {
619+
/* Set output format */
620+
switch (config->fmts[i].width_min) {
621+
case 160: /* QQVGA */
622+
ret = video_write_cci_multiregs8(&config->bus, ov7675_regs_qqvga,
623+
ARRAY_SIZE(ov7675_regs_qqvga));
624+
break;
625+
case 320: /* QVGA */
626+
ret = video_write_cci_multiregs8(&config->bus, ov7675_regs_qvga,
627+
ARRAY_SIZE(ov7675_regs_qvga));
628+
break;
629+
case 640: /* VGA */
630+
ret = video_write_cci_multiregs8(&config->bus, ov7675_regs_vga,
631+
ARRAY_SIZE(ov7675_regs_vga));
632+
break;
633+
default: /* QVGA */
634+
ret = video_write_cci_multiregs8(&config->bus, ov7675_regs_qvga,
635+
ARRAY_SIZE(ov7675_regs_qvga));
636+
break;
637+
}
638+
if (ret < 0) {
639+
LOG_ERR("Resolution not set!");
640+
return ret;
571641
}
572-
i++;
573642
}
643+
i++;
574644
}
575-
576645
if (ret < 0) {
577646
LOG_ERR("Resolution not supported!");
578647
return ret;
579648
}
580649

581650
return 0;
582651
}
652+
#endif
653+
654+
static int ov767x_set_fmt(const struct device *dev, struct video_format *fmt)
655+
{
656+
int ret;
657+
658+
if (fmt->pixelformat != VIDEO_PIX_FMT_RGB565 && fmt->pixelformat != VIDEO_PIX_FMT_YUYV) {
659+
LOG_ERR("Only RGB565 and YUYV supported!");
660+
return -ENOTSUP;
661+
}
662+
663+
#if DT_HAS_COMPAT_STATUS_OKAY(ovti_ov7670)
664+
ret = ov7670_set_fmt(dev, fmt);
665+
if (ret < 0) {
666+
return ret;
667+
}
668+
#endif
669+
#if DT_HAS_COMPAT_STATUS_OKAY(ovti_ov7675)
670+
ret = ov7675_set_fmt(dev, fmt);
671+
if (ret < 0) {
672+
return ret;
673+
}
674+
#endif
675+
676+
return 0;
677+
}
583678

584679
static int ov767x_get_fmt(const struct device *dev, struct video_format *fmt)
585680
{
@@ -689,7 +784,9 @@ static int ov767x_init(const struct device *dev)
689784
}
690785
/* Delay after reset */
691786
k_msleep(5);
787+
692788
ret = ov767x_set_fmt(dev, &fmt);
789+
693790
if (ret < 0) {
694791
return ret;
695792
}

0 commit comments

Comments
 (0)