@@ -706,10 +706,16 @@ static const struct video_reg8 default_regs[] = {
706
706
{0x46 , 0xcf },
707
707
708
708
{GC2145_REG_RESET , GC2145_REG_RESET_P0_REGS },
709
+ /* Hb and Vb from Teensy_camera */
709
710
{0x05 , 0x01 },
710
- {0x06 , 0x1C },
711
- {0x07 , 0x00 },
712
- {0x08 , 0x32 },
711
+ {0x06 , 0x3b },
712
+ {0x07 , 0x01 },
713
+ {0x08 , 0x0b },
714
+ /* Hb and Vb from current */
715
+ /*{0x05, 0x01}, */
716
+ /*{0x06, 0x1C}, */
717
+ /*{0x07, 0x00}, */
718
+ /*{0x08, 0x32}, */
713
719
{0x11 , 0x00 },
714
720
{0x12 , 0x1D },
715
721
{0x13 , 0x00 },
@@ -768,12 +774,22 @@ struct gc2145_ctrls {
768
774
struct gc2145_data {
769
775
struct gc2145_ctrls ctrls ;
770
776
struct video_format fmt ;
777
+ struct video_rect crop ;
778
+ uint8_t c_ratio ;
779
+ uint8_t r_ratio ;
771
780
};
772
781
773
- #define GC2145_VIDEO_FORMAT_CAP (width , height , format ) \
774
- { \
775
- .pixelformat = format, .width_min = width, .width_max = width, \
776
- .height_min = height, .height_max = height, .width_step = 0, .height_step = 0, \
782
+ #define USE_ONE_FORMAT_WIDTH_HEIGHT
783
+ #define GC2145_VIDEO_FORMAT_CAP (width , height , format ) \
784
+ { \
785
+ .pixelformat = format, .width_min = width, .width_max = width, \
786
+ .height_min = height, .height_max = height, .width_step = 0, .height_step = 0, \
787
+ }
788
+
789
+ #define GC2145_VIDEO_FORMAT_CAP_HL (width_l , width_h , height_l , height_h , format ) \
790
+ { \
791
+ .pixelformat = format, .width_min = width_l, .width_max = width_h, \
792
+ .height_min = height_l, .height_max = height_h, .width_step = 0, .height_step = 0,\
777
793
}
778
794
779
795
#define RESOLUTION_QVGA_W 320
@@ -786,12 +802,22 @@ struct gc2145_data {
786
802
#define RESOLUTION_UXGA_H 1200
787
803
788
804
static const struct video_format_cap fmts [] = {
805
+ #ifdef USE_ONE_FORMAT_WIDTH_HEIGHT
806
+ GC2145_VIDEO_FORMAT_CAP_HL (128 , 1600 , 128 , 1200 , VIDEO_PIX_FMT_RGB565 ),
807
+ GC2145_VIDEO_FORMAT_CAP_HL (128 , 1600 , 128 , 1200 , VIDEO_PIX_FMT_YUYV ),
808
+ #else
789
809
GC2145_VIDEO_FORMAT_CAP (RESOLUTION_QVGA_W , RESOLUTION_QVGA_H , VIDEO_PIX_FMT_RGB565 ),
790
810
GC2145_VIDEO_FORMAT_CAP (RESOLUTION_VGA_W , RESOLUTION_VGA_H , VIDEO_PIX_FMT_RGB565 ),
791
811
GC2145_VIDEO_FORMAT_CAP (RESOLUTION_UXGA_W , RESOLUTION_UXGA_H , VIDEO_PIX_FMT_RGB565 ),
812
+ /* Add some full size possible resolutions */
813
+ GC2145_VIDEO_FORMAT_CAP (800 , 600 , VIDEO_PIX_FMT_RGB565 ), /* div 2 */
814
+ GC2145_VIDEO_FORMAT_CAP (533 , 400 , VIDEO_PIX_FMT_RGB565 ), /* div 3 */
815
+ GC2145_VIDEO_FORMAT_CAP (400 , 300 , VIDEO_PIX_FMT_RGB565 ), /* div 4 */
816
+ GC2145_VIDEO_FORMAT_CAP (320 , 240 , VIDEO_PIX_FMT_RGB565 ), /* div 5 */
792
817
GC2145_VIDEO_FORMAT_CAP (RESOLUTION_QVGA_W , RESOLUTION_QVGA_H , VIDEO_PIX_FMT_YUYV ),
793
818
GC2145_VIDEO_FORMAT_CAP (RESOLUTION_VGA_W , RESOLUTION_VGA_H , VIDEO_PIX_FMT_YUYV ),
794
819
GC2145_VIDEO_FORMAT_CAP (RESOLUTION_UXGA_W , RESOLUTION_UXGA_H , VIDEO_PIX_FMT_YUYV ),
820
+ #endif
795
821
{0 },
796
822
};
797
823
@@ -843,47 +869,52 @@ static int gc2145_set_output_format(const struct device *dev, int output_format)
843
869
return 0 ;
844
870
}
845
871
846
- static int gc2145_set_resolution (const struct device * dev , uint32_t w , uint32_t h )
872
+
873
+ static int gc2145_set_resolution (const struct device * dev , uint32_t w , uint32_t h ,
874
+ bool compute_ratio )
847
875
{
848
876
const struct gc2145_config * cfg = dev -> config ;
877
+ struct gc2145_data * drv_data = dev -> data ;
849
878
int ret ;
850
879
851
880
uint16_t win_w ;
852
881
uint16_t win_h ;
853
- uint16_t c_ratio ;
854
- uint16_t r_ratio ;
855
882
uint16_t x ;
856
883
uint16_t y ;
857
884
uint16_t win_x ;
858
885
uint16_t win_y ;
859
886
860
- /* Add the subsampling factor depending on resolution */
861
- switch (w ) {
862
- case RESOLUTION_QVGA_W :
863
- c_ratio = 3 ;
864
- r_ratio = 3 ;
865
- break ;
866
- case RESOLUTION_VGA_W :
867
- c_ratio = 2 ;
868
- r_ratio = 2 ;
869
- break ;
870
- case RESOLUTION_UXGA_W :
871
- c_ratio = 1 ;
872
- r_ratio = 1 ;
873
- break ;
874
- default :
875
- LOG_ERR ("Unsupported resolution %d %d" , w , h );
887
+ if ((w == 0 ) || (h == 0 )) {
876
888
return - EIO ;
877
- };
889
+ }
890
+ drv_data -> c_ratio = RESOLUTION_UXGA_W / w ;
891
+ drv_data -> r_ratio = RESOLUTION_UXGA_H / h ;
892
+ if (drv_data -> c_ratio < drv_data -> r_ratio ) {
893
+ drv_data -> r_ratio = drv_data -> c_ratio ;
894
+ } else {
895
+ drv_data -> c_ratio = drv_data -> r_ratio ;
896
+ }
897
+
898
+ /* make sure we don't end up with ratio of 0 */
899
+ if (drv_data -> c_ratio == 0 ) {
900
+ return - EIO ;
901
+ }
878
902
879
903
/* Calculates the window boundaries to obtain the desired resolution */
880
- win_w = w * c_ratio ;
881
- win_h = h * r_ratio ;
882
- x = (((win_w / c_ratio ) - w ) / 2 );
883
- y = (((win_h / r_ratio ) - h ) / 2 );
904
+
905
+ win_w = w * drv_data -> c_ratio ;
906
+ win_h = h * drv_data -> r_ratio ;
884
907
win_x = ((UXGA_HSIZE - win_w ) / 2 );
885
908
win_y = ((UXGA_VSIZE - win_h ) / 2 );
886
909
910
+ drv_data -> crop .left = 0 ;
911
+ drv_data -> crop .top = 0 ;
912
+ drv_data -> crop .width = w ;
913
+ drv_data -> crop .height = h ;
914
+
915
+ x = (((win_w / drv_data -> c_ratio ) - w ) / 2 );
916
+ y = (((win_h / drv_data -> r_ratio ) - h ) / 2 );
917
+
887
918
ret = video_write_cci_reg (& cfg -> i2c , GC2145_REG8 (GC2145_REG_RESET ),
888
919
GC2145_REG_RESET_P0_REGS );
889
920
if (ret < 0 ) {
@@ -933,7 +964,8 @@ static int gc2145_set_resolution(const struct device *dev, uint32_t w, uint32_t
933
964
}
934
965
935
966
/* Set Sub-sampling ratio and mode */
936
- ret = video_write_cci_reg (& cfg -> i2c , GC2145_REG_SUBSAMPLE , ((r_ratio << 4 ) | c_ratio ));
967
+ ret = video_write_cci_reg (& cfg -> i2c , GC2145_REG_SUBSAMPLE ,
968
+ ((drv_data -> r_ratio << 4 ) | drv_data -> c_ratio ));
937
969
if (ret < 0 ) {
938
970
return ret ;
939
971
}
@@ -954,6 +986,32 @@ static int gc2145_set_resolution(const struct device *dev, uint32_t w, uint32_t
954
986
return 0 ;
955
987
}
956
988
989
+ static int gc2145_set_crop (const struct device * dev )
990
+ {
991
+ /* set the crop, start off with most of a duplicate of set resolution */
992
+ int ret ;
993
+ struct gc2145_data * drv_data = dev -> data ;
994
+
995
+ /* Calculates the window boundaries to obtain the desired resolution */
996
+ if ((drv_data -> fmt .width == drv_data -> crop .width ) &&
997
+ (drv_data -> fmt .height == drv_data -> crop .height )) {
998
+ return 0 ;
999
+ }
1000
+
1001
+ LOG_DBG ("set_res: %u %u ratios: %u %u" , drv_data -> crop .width , drv_data -> crop .height ,
1002
+ drv_data -> c_ratio , drv_data -> r_ratio );
1003
+ ret = gc2145_set_resolution (dev , drv_data -> crop .width , drv_data -> crop .height , false);
1004
+ if (ret == 0 ) {
1005
+ /* enqueue/dequeue depend on this being set as well as the crop */
1006
+ drv_data -> fmt .width = drv_data -> crop .width ;
1007
+ drv_data -> fmt .height = drv_data -> crop .height ;
1008
+ drv_data -> fmt .pitch = drv_data -> fmt .width
1009
+ * video_bits_per_pixel (drv_data -> fmt .pixelformat ) / BITS_PER_BYTE ;
1010
+ }
1011
+ return ret ;
1012
+ }
1013
+
1014
+
957
1015
static int gc2145_check_connection (const struct device * dev )
958
1016
{
959
1017
const struct gc2145_config * cfg = dev -> config ;
@@ -1057,7 +1115,10 @@ static int gc2145_set_fmt(const struct device *dev, struct video_format *fmt)
1057
1115
1058
1116
/* Check if camera is capable of handling given format */
1059
1117
for (int i = 0 ; i < ARRAY_SIZE (fmts ) - 1 ; i ++ ) {
1060
- if (fmts [i ].width_min == fmt -> width && fmts [i ].height_min == fmt -> height &&
1118
+ if ((fmts [i ].width_min <= fmt -> width ) &&
1119
+ (fmts [i ].width_max >= fmt -> width ) &&
1120
+ (fmts [i ].height_min <= fmt -> height ) &&
1121
+ (fmts [i ].height_max >= fmt -> height ) &&
1061
1122
fmts [i ].pixelformat == fmt -> pixelformat ) {
1062
1123
res = i ;
1063
1124
break ;
@@ -1076,7 +1137,7 @@ static int gc2145_set_fmt(const struct device *dev, struct video_format *fmt)
1076
1137
}
1077
1138
1078
1139
/* Set window size */
1079
- ret = gc2145_set_resolution (dev , fmt -> width , fmt -> height );
1140
+ ret = gc2145_set_resolution (dev , fmt -> width , fmt -> height , true );
1080
1141
1081
1142
if (ret < 0 ) {
1082
1143
LOG_ERR ("Failed to set the resolution" );
@@ -1171,12 +1232,60 @@ static int gc2145_set_ctrl(const struct device *dev, uint32_t id)
1171
1232
}
1172
1233
}
1173
1234
1235
+ static int gc2145_set_selection (const struct device * dev , struct video_selection * sel )
1236
+ {
1237
+ LOG_DBG ("called: (%p, %p: %u %u)" , dev , sel , sel -> type , sel -> target );
1238
+ if (sel -> type != VIDEO_BUF_TYPE_OUTPUT ) {
1239
+ return - EINVAL ;
1240
+ }
1241
+
1242
+ struct gc2145_data * drv_data = dev -> data ;
1243
+
1244
+ if (sel -> target == VIDEO_SEL_TGT_CROP ) {
1245
+ drv_data -> crop = sel -> rect ;
1246
+ return gc2145_set_crop (dev );
1247
+ }
1248
+
1249
+ return - EINVAL ;
1250
+ }
1251
+
1252
+ static int gc2145_get_selection (const struct device * dev , struct video_selection * sel )
1253
+ {
1254
+ LOG_DBG ("called: (%p, %p: %u %u)" , dev , sel , sel -> type , sel -> target );
1255
+ if (sel -> type != VIDEO_BUF_TYPE_OUTPUT ) {
1256
+ return - EINVAL ;
1257
+ }
1258
+
1259
+ struct gc2145_data * drv_data = dev -> data ;
1260
+
1261
+ switch (sel -> target ) {
1262
+ case VIDEO_SEL_TGT_COMPOSE :
1263
+ case VIDEO_SEL_TGT_CROP :
1264
+ sel -> rect = drv_data -> crop ;
1265
+ break ;
1266
+
1267
+ case VIDEO_SEL_TGT_NATIVE_SIZE :
1268
+ sel -> rect .top = 0 ;
1269
+ sel -> rect .left = 0 ;
1270
+ sel -> rect .width = UXGA_HSIZE / drv_data -> c_ratio ;
1271
+ sel -> rect .height = UXGA_VSIZE / drv_data -> r_ratio ;
1272
+ break ;
1273
+ default :
1274
+ return - EINVAL ;
1275
+ }
1276
+
1277
+ return 0 ;
1278
+ }
1279
+
1280
+
1174
1281
static DEVICE_API (video , gc2145_driver_api ) = {
1175
1282
.set_format = gc2145_set_fmt ,
1176
1283
.get_format = gc2145_get_fmt ,
1177
1284
.get_caps = gc2145_get_caps ,
1178
1285
.set_stream = gc2145_set_stream ,
1179
1286
.set_ctrl = gc2145_set_ctrl ,
1287
+ .set_selection = gc2145_set_selection ,
1288
+ .get_selection = gc2145_get_selection ,
1180
1289
};
1181
1290
1182
1291
static int gc2145_init_controls (const struct device * dev )
@@ -1214,8 +1323,8 @@ static int gc2145_init(const struct device *dev)
1214
1323
/* set default/init format VGA RGB565 */
1215
1324
struct video_format fmt = {
1216
1325
.pixelformat = VIDEO_PIX_FMT_RGB565 ,
1217
- .width = RESOLUTION_VGA_W ,
1218
- .height = RESOLUTION_VGA_H ,
1326
+ .width = RESOLUTION_QVGA_W ,
1327
+ .height = RESOLUTION_QVGA_H ,
1219
1328
};
1220
1329
int ret ;
1221
1330
const struct gc2145_config * cfg = dev -> config ;
0 commit comments