@@ -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
709712static 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
716721static 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