Skip to content

Commit 2924a99

Browse files
iabdalkaderkartben
authored andcommitted
drivers: video: gc2145: Add support for YUV format.
Can be used to get a fast grayscale image. Signed-off-by: Ibrahim Abdalkader <[email protected]>
1 parent 5b74f00 commit 2924a99

File tree

1 file changed

+37
-42
lines changed

1 file changed

+37
-42
lines changed

drivers/video/gc2145.c

+37-42
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ LOG_MODULE_REGISTER(video_gc2145, CONFIG_VIDEO_LOG_LEVEL);
2121
#define GC2145_REG_AMODE1_DEF 0x14
2222
#define GC2145_REG_OUTPUT_FMT 0x84
2323
#define GC2145_REG_OUTPUT_FMT_RGB565 0x06
24+
#define GC2145_REG_OUTPUT_FMT_YCBYCR 0x02
2425
#define GC2145_REG_SYNC_MODE 0x86
2526
#define GC2145_REG_SYNC_MODE_DEF 0x23
2627
#define GC2145_REG_SYNC_MODE_COL_SWITCH 0x10
@@ -699,18 +700,22 @@ struct gc2145_data {
699700
.height_min = height, .height_max = height, .width_step = 0, .height_step = 0, \
700701
}
701702

702-
enum resolutions {
703-
QVGA_RESOLUTION = 0,
704-
VGA_RESOLUTION,
705-
UXGA_RESOLUTION,
706-
RESOLUTIONS_MAX,
707-
};
703+
#define RESOLUTION_QVGA_W 320
704+
#define RESOLUTION_QVGA_H 240
705+
706+
#define RESOLUTION_VGA_W 640
707+
#define RESOLUTION_VGA_H 480
708+
709+
#define RESOLUTION_UXGA_W 1600
710+
#define RESOLUTION_UXGA_H 1200
708711

709712
static const struct video_format_cap fmts[] = {
710-
[QVGA_RESOLUTION] = GC2145_VIDEO_FORMAT_CAP(320, 240, VIDEO_PIX_FMT_RGB565), /* QVGA */
711-
[VGA_RESOLUTION] = GC2145_VIDEO_FORMAT_CAP(640, 480, VIDEO_PIX_FMT_RGB565), /* VGA */
712-
[UXGA_RESOLUTION] = GC2145_VIDEO_FORMAT_CAP(1600, 1200, VIDEO_PIX_FMT_RGB565), /* UXGA */
713-
[RESOLUTIONS_MAX] = {0},
713+
GC2145_VIDEO_FORMAT_CAP(RESOLUTION_QVGA_W, RESOLUTION_QVGA_H, VIDEO_PIX_FMT_RGB565),
714+
GC2145_VIDEO_FORMAT_CAP(RESOLUTION_VGA_W, RESOLUTION_VGA_H, VIDEO_PIX_FMT_RGB565),
715+
GC2145_VIDEO_FORMAT_CAP(RESOLUTION_UXGA_W, RESOLUTION_UXGA_H, VIDEO_PIX_FMT_RGB565),
716+
GC2145_VIDEO_FORMAT_CAP(RESOLUTION_QVGA_W, RESOLUTION_QVGA_H, VIDEO_PIX_FMT_YUYV),
717+
GC2145_VIDEO_FORMAT_CAP(RESOLUTION_VGA_W, RESOLUTION_VGA_H, VIDEO_PIX_FMT_YUYV),
718+
GC2145_VIDEO_FORMAT_CAP(RESOLUTION_UXGA_W, RESOLUTION_UXGA_H, VIDEO_PIX_FMT_YUYV),
714719
};
715720

716721
static int gc2145_write_reg(const struct i2c_dt_spec *spec, uint8_t reg_addr, uint8_t value)
@@ -893,13 +898,17 @@ static int gc2145_set_output_format(const struct device *dev, int output_format)
893898
return ret;
894899
}
895900

896-
if (output_format != VIDEO_PIX_FMT_RGB565) {
901+
/* Map format to sensor format */
902+
if (output_format == VIDEO_PIX_FMT_RGB565) {
903+
output_format = GC2145_REG_OUTPUT_FMT_RGB565;
904+
} else if (output_format == VIDEO_PIX_FMT_YUYV) {
905+
output_format = GC2145_REG_OUTPUT_FMT_YCBYCR;
906+
} else {
897907
LOG_ERR("Image format not supported");
898908
return -ENOTSUP;
899909
}
900910

901-
/* Disable JPEG compression and set output to RGB565 */
902-
ret = gc2145_write_reg(&cfg->i2c, GC2145_REG_OUTPUT_FMT, GC2145_REG_OUTPUT_FMT_RGB565);
911+
ret = gc2145_write_reg(&cfg->i2c, GC2145_REG_OUTPUT_FMT, output_format);
903912
if (ret < 0) {
904913
return ret;
905914
}
@@ -909,13 +918,11 @@ static int gc2145_set_output_format(const struct device *dev, int output_format)
909918
return 0;
910919
}
911920

912-
static int gc2145_set_resolution(const struct device *dev, enum resolutions res)
921+
static int gc2145_set_resolution(const struct device *dev, uint32_t w, uint32_t h)
913922
{
914923
int ret;
915924
const struct gc2145_config *cfg = dev->config;
916925

917-
uint16_t w;
918-
uint16_t h;
919926
uint16_t win_w;
920927
uint16_t win_h;
921928
uint16_t c_ratio;
@@ -925,29 +932,22 @@ static int gc2145_set_resolution(const struct device *dev, enum resolutions res)
925932
uint16_t win_x;
926933
uint16_t win_y;
927934

928-
if (res >= RESOLUTIONS_MAX) {
929-
return -EIO;
930-
}
931-
932-
w = fmts[res].width_min;
933-
h = fmts[res].height_min;
934-
935935
/* Add the subsampling factor depending on resolution */
936-
switch (res) {
937-
case QVGA_RESOLUTION:
936+
switch (w) {
937+
case RESOLUTION_QVGA_W:
938938
c_ratio = 3;
939939
r_ratio = 3;
940940
break;
941-
case VGA_RESOLUTION:
941+
case RESOLUTION_VGA_W:
942942
c_ratio = 2;
943943
r_ratio = 2;
944944
break;
945-
case UXGA_RESOLUTION:
945+
case RESOLUTION_UXGA_W:
946946
c_ratio = 1;
947947
r_ratio = 1;
948948
break;
949949
default:
950-
LOG_ERR("Unsupported resolution %d", res);
950+
LOG_ERR("Unsupported resolution %d %d", w, h);
951951
return -EIO;
952952
};
953953

@@ -1027,29 +1027,23 @@ static int gc2145_set_fmt(const struct device *dev, enum video_endpoint_id ep,
10271027
struct video_format *fmt)
10281028
{
10291029
struct gc2145_data *drv_data = dev->data;
1030-
enum resolutions res = RESOLUTIONS_MAX;
1030+
size_t res = ARRAY_SIZE(fmts);
10311031
int ret;
10321032

1033-
/* We only support RGB565 formats */
1034-
if (fmt->pixelformat != VIDEO_PIX_FMT_RGB565) {
1035-
LOG_ERR("gc2145 camera supports only RGB565");
1036-
return -ENOTSUP;
1037-
}
1038-
10391033
if (memcmp(&drv_data->fmt, fmt, sizeof(drv_data->fmt)) == 0) {
10401034
/* nothing to do */
10411035
return 0;
10421036
}
10431037

10441038
/* Check if camera is capable of handling given format */
1045-
for (int i = 0; i < RESOLUTIONS_MAX; i++) {
1039+
for (int i = 0; i < ARRAY_SIZE(fmts); i++) {
10461040
if (fmts[i].width_min == fmt->width && fmts[i].height_min == fmt->height &&
10471041
fmts[i].pixelformat == fmt->pixelformat) {
1048-
res = (enum resolutions)i;
1042+
res = i;
10491043
break;
10501044
}
10511045
}
1052-
if (res == RESOLUTIONS_MAX) {
1046+
if (res == ARRAY_SIZE(fmts)) {
10531047
LOG_ERR("Image format not supported");
10541048
return -ENOTSUP;
10551049
}
@@ -1064,7 +1058,8 @@ static int gc2145_set_fmt(const struct device *dev, enum video_endpoint_id ep,
10641058
}
10651059

10661060
/* Set window size */
1067-
ret = gc2145_set_resolution(dev, res);
1061+
ret = gc2145_set_resolution(dev, fmt->width, fmt->height);
1062+
10681063
if (ret < 0) {
10691064
LOG_ERR("Failed to set the resolution");
10701065
return ret;
@@ -1161,9 +1156,9 @@ static int gc2145_init(const struct device *dev)
11611156

11621157
/* set default/init format QVGA RGB565 */
11631158
fmt.pixelformat = VIDEO_PIX_FMT_RGB565;
1164-
fmt.width = fmts[QVGA_RESOLUTION].width_min;
1165-
fmt.height = fmts[QVGA_RESOLUTION].height_min;
1166-
fmt.pitch = fmts[QVGA_RESOLUTION].width_min * 2;
1159+
fmt.width = RESOLUTION_QVGA_W;
1160+
fmt.height = RESOLUTION_QVGA_H;
1161+
fmt.pitch = RESOLUTION_QVGA_W * 2;
11671162

11681163
ret = gc2145_set_fmt(dev, VIDEO_EP_OUT, &fmt);
11691164
if (ret) {

0 commit comments

Comments
 (0)