@@ -145,7 +145,11 @@ struct ov5640_mode_config {
145
145
};
146
146
147
147
struct ov5640_ctrls {
148
- struct video_ctrl gain ;
148
+ /* gain auto-cluster */
149
+ struct {
150
+ struct video_ctrl auto_gain ;
151
+ struct video_ctrl gain ;
152
+ };
149
153
struct video_ctrl brightness ;
150
154
struct video_ctrl contrast ;
151
155
struct video_ctrl hue ;
@@ -1034,24 +1038,30 @@ static int ov5640_set_ctrl_contrast(const struct device *dev, int value)
1034
1038
return ov5640_write_reg (& cfg -> i2c , SDE_CTRL6_REG , value & 0xff );
1035
1039
}
1036
1040
1037
- static int ov5640_set_ctrl_gain (const struct device * dev , int value )
1041
+ static int ov5640_set_ctrl_gain (const struct device * dev )
1038
1042
{
1039
1043
const struct ov5640_config * cfg = dev -> config ;
1044
+ struct ov5640_data * drv_data = dev -> data ;
1045
+ struct ov5640_ctrls * ctrls = & drv_data -> ctrls ;
1040
1046
1041
- if (value ) {
1042
- int ret = ov5640_modify_reg (& cfg -> i2c , AEC_PK_MANUAL , BIT (1 ), BIT (0 ));
1047
+ int ret = ov5640_modify_reg (& cfg -> i2c , AEC_PK_MANUAL , BIT (1 ),
1048
+ ctrls -> auto_gain .val ? 0 : BIT (1 ));
1049
+
1050
+ if (ret ) {
1051
+ return ret ;
1052
+ }
1043
1053
1054
+ if (!ctrls -> auto_gain .val ) {
1055
+ ret = ov5640_modify_reg (& cfg -> i2c , AEC_PK_REAL_GAIN , 0x03 ,
1056
+ (ctrls -> gain .val >> 8 ) & 0x03 );
1044
1057
if (ret ) {
1045
1058
return ret ;
1046
1059
}
1047
1060
1048
- struct ov5640_reg gain_params [] = {{AEC_PK_REAL_GAIN , value >> 8 },
1049
- {AEC_PK_REAL_GAIN + 1 , value & 0xff }};
1050
-
1051
- return ov5640_write_multi_regs (& cfg -> i2c , gain_params , ARRAY_SIZE (gain_params ));
1052
- } else {
1053
- return ov5640_write_reg (& cfg -> i2c , AEC_PK_MANUAL , 0 );
1061
+ ret = ov5640_write_reg (& cfg -> i2c , AEC_PK_REAL_GAIN + 1 , ctrls -> gain .val & 0xff );
1054
1062
}
1063
+
1064
+ return ret ;
1055
1065
}
1056
1066
1057
1067
static int ov5640_set_ctrl_hflip (const struct device * dev , int value )
@@ -1096,32 +1106,68 @@ static int ov5640_set_ctrl_power_line_freq(const struct device *dev, int value)
1096
1106
return ov5640_modify_reg (& cfg -> i2c , HZ5060_CTRL01_REG , BIT (7 ), BIT (7 ));
1097
1107
}
1098
1108
1099
- static int ov5640_set_ctrl (const struct device * dev , struct video_control * ctrl )
1109
+ static int ov5640_set_ctrl (const struct device * dev , uint32_t id )
1100
1110
{
1101
- switch (ctrl -> id ) {
1111
+ struct ov5640_data * drv_data = dev -> data ;
1112
+ struct ov5640_ctrls * ctrls = & drv_data -> ctrls ;
1113
+
1114
+ switch (id ) {
1102
1115
case VIDEO_CID_TEST_PATTERN :
1103
- return ov5640_set_ctrl_test_pattern (dev , ctrl -> val );
1116
+ return ov5640_set_ctrl_test_pattern (dev , ctrls -> test_pattern . val );
1104
1117
case VIDEO_CID_HUE :
1105
- return ov5640_set_ctrl_hue (dev , ctrl -> val );
1118
+ return ov5640_set_ctrl_hue (dev , ctrls -> hue . val );
1106
1119
case VIDEO_CID_SATURATION :
1107
- return ov5640_set_ctrl_saturation (dev , ctrl -> val );
1120
+ return ov5640_set_ctrl_saturation (dev , ctrls -> saturation . val );
1108
1121
case VIDEO_CID_BRIGHTNESS :
1109
- return ov5640_set_ctrl_brightness (dev , ctrl -> val );
1122
+ return ov5640_set_ctrl_brightness (dev , ctrls -> brightness . val );
1110
1123
case VIDEO_CID_CONTRAST :
1111
- return ov5640_set_ctrl_contrast (dev , ctrl -> val );
1112
- case VIDEO_CID_GAIN :
1113
- return ov5640_set_ctrl_gain (dev , ctrl -> val );
1124
+ return ov5640_set_ctrl_contrast (dev , ctrls -> contrast . val );
1125
+ case VIDEO_CID_AUTOGAIN :
1126
+ return ov5640_set_ctrl_gain (dev );
1114
1127
case VIDEO_CID_HFLIP :
1115
- return ov5640_set_ctrl_hflip (dev , ctrl -> val );
1128
+ return ov5640_set_ctrl_hflip (dev , ctrls -> hflip . val );
1116
1129
case VIDEO_CID_VFLIP :
1117
- return ov5640_set_ctrl_vflip (dev , ctrl -> val );
1130
+ return ov5640_set_ctrl_vflip (dev , ctrls -> vflip . val );
1118
1131
case VIDEO_CID_POWER_LINE_FREQUENCY :
1119
- return ov5640_set_ctrl_power_line_freq (dev , ctrl -> val );
1132
+ return ov5640_set_ctrl_power_line_freq (dev , ctrls -> light_freq . val );
1120
1133
default :
1121
1134
return - ENOTSUP ;
1122
1135
}
1123
1136
}
1124
1137
1138
+ static int ov5640_get_gain (const struct device * dev )
1139
+ {
1140
+ int ret ;
1141
+ uint16_t gain ;
1142
+ const struct ov5640_config * cfg = dev -> config ;
1143
+
1144
+ ret = ov5640_read_reg (& cfg -> i2c , AEC_PK_REAL_GAIN , & gain , sizeof (gain ));
1145
+ if (ret ) {
1146
+ return ret ;
1147
+ }
1148
+
1149
+ return gain & 0x3ff ;
1150
+ }
1151
+
1152
+ static int ov5640_get_volatile_ctrl (const struct device * dev , uint32_t id )
1153
+ {
1154
+ int val ;
1155
+ struct ov5640_data * drv_data = dev -> data ;
1156
+ struct ov5640_ctrls * ctrls = & drv_data -> ctrls ;
1157
+
1158
+ switch (id ) {
1159
+ case VIDEO_CID_AUTOGAIN :
1160
+ val = ov5640_get_gain (dev );
1161
+ if (val < 0 ) {
1162
+ return val ;
1163
+ }
1164
+ ctrls -> gain .val = val ;
1165
+ break ;
1166
+ }
1167
+
1168
+ return 0 ;
1169
+ }
1170
+
1125
1171
static int ov5640_get_frmival (const struct device * dev , enum video_endpoint_id ep ,
1126
1172
struct video_frmival * frmival )
1127
1173
{
@@ -1171,6 +1217,7 @@ static DEVICE_API(video, ov5640_driver_api) = {
1171
1217
.get_caps = ov5640_get_caps ,
1172
1218
.set_stream = ov5640_set_stream ,
1173
1219
.set_ctrl = ov5640_set_ctrl ,
1220
+ .get_volatile_ctrl = ov5640_get_volatile_ctrl ,
1174
1221
.set_frmival = ov5640_set_frmival ,
1175
1222
.get_frmival = ov5640_get_frmival ,
1176
1223
.enum_frmival = ov5640_enum_frmival ,
@@ -1182,13 +1229,21 @@ static int ov5640_init_controls(const struct device *dev)
1182
1229
struct ov5640_data * drv_data = dev -> data ;
1183
1230
struct ov5640_ctrls * ctrls = & drv_data -> ctrls ;
1184
1231
1232
+ ret = video_init_ctrl (& ctrls -> auto_gain , dev , VIDEO_CID_AUTOGAIN ,
1233
+ (struct video_ctrl_range ){.min = 0 , .max = 1 , .step = 1 , .def = 1 });
1234
+ if (ret ) {
1235
+ return ret ;
1236
+ }
1237
+
1185
1238
ret = video_init_ctrl (
1186
- & ctrls -> gain , dev , VIDEO_CID_GAIN ,
1239
+ & ctrls -> gain , dev , VIDEO_CID_ANALOGUE_GAIN ,
1187
1240
(struct video_ctrl_range ){.min = 0 , .max = 1023 , .step = 1 , .def = 0 });
1188
1241
if (ret ) {
1189
1242
return ret ;
1190
1243
}
1191
1244
1245
+ video_auto_cluster_ctrl (& ctrls -> auto_gain , 2 , true);
1246
+
1192
1247
ret = video_init_ctrl (
1193
1248
& ctrls -> brightness , dev , VIDEO_CID_BRIGHTNESS ,
1194
1249
(struct video_ctrl_range ){.min = -15 , .max = 15 , .step = 1 , .def = 0 });
0 commit comments