diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/ov7670.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c index 95507770f120..e7555d1f90e6 100644 --- a/drivers/media/video/ov7670.c +++ b/drivers/media/video/ov7670.c | |||
@@ -1131,6 +1131,67 @@ static int ov7670_s_vflip(struct v4l2_subdev *sd, int value) | |||
1131 | return ret; | 1131 | return ret; |
1132 | } | 1132 | } |
1133 | 1133 | ||
1134 | /* | ||
1135 | * GAIN is split between REG_GAIN and REG_VREF[7:6]. If one believes | ||
1136 | * the data sheet, the VREF parts should be the most significant, but | ||
1137 | * experience shows otherwise. There seems to be little value in | ||
1138 | * messing with the VREF bits, so we leave them alone. | ||
1139 | */ | ||
1140 | static int ov7670_g_gain(struct v4l2_subdev *sd, __s32 *value) | ||
1141 | { | ||
1142 | int ret; | ||
1143 | unsigned char gain; | ||
1144 | |||
1145 | ret = ov7670_read(sd, REG_GAIN, &gain); | ||
1146 | *value = gain; | ||
1147 | return ret; | ||
1148 | } | ||
1149 | |||
1150 | static int ov7670_s_gain(struct v4l2_subdev *sd, int value) | ||
1151 | { | ||
1152 | int ret; | ||
1153 | unsigned char com8; | ||
1154 | |||
1155 | ret = ov7670_write(sd, REG_GAIN, value & 0xff); | ||
1156 | /* Have to turn off AGC as well */ | ||
1157 | if (ret == 0) { | ||
1158 | ret = ov7670_read(sd, REG_COM8, &com8); | ||
1159 | ret = ov7670_write(sd, REG_COM8, com8 & ~COM8_AGC); | ||
1160 | } | ||
1161 | return ret; | ||
1162 | } | ||
1163 | |||
1164 | /* | ||
1165 | * Tweak autogain. | ||
1166 | */ | ||
1167 | static int ov7670_g_autogain(struct v4l2_subdev *sd, __s32 *value) | ||
1168 | { | ||
1169 | int ret; | ||
1170 | unsigned char com8; | ||
1171 | |||
1172 | ret = ov7670_read(sd, REG_COM8, &com8); | ||
1173 | *value = (com8 & COM8_AGC) != 0; | ||
1174 | return ret; | ||
1175 | } | ||
1176 | |||
1177 | static int ov7670_s_autogain(struct v4l2_subdev *sd, int value) | ||
1178 | { | ||
1179 | int ret; | ||
1180 | unsigned char com8; | ||
1181 | |||
1182 | ret = ov7670_read(sd, REG_COM8, &com8); | ||
1183 | if (ret == 0) { | ||
1184 | if (value) | ||
1185 | com8 |= COM8_AGC; | ||
1186 | else | ||
1187 | com8 &= ~COM8_AGC; | ||
1188 | ret = ov7670_write(sd, REG_COM8, com8); | ||
1189 | } | ||
1190 | return ret; | ||
1191 | } | ||
1192 | |||
1193 | |||
1194 | |||
1134 | static int ov7670_queryctrl(struct v4l2_subdev *sd, | 1195 | static int ov7670_queryctrl(struct v4l2_subdev *sd, |
1135 | struct v4l2_queryctrl *qc) | 1196 | struct v4l2_queryctrl *qc) |
1136 | { | 1197 | { |
@@ -1147,6 +1208,10 @@ static int ov7670_queryctrl(struct v4l2_subdev *sd, | |||
1147 | return v4l2_ctrl_query_fill(qc, 0, 256, 1, 128); | 1208 | return v4l2_ctrl_query_fill(qc, 0, 256, 1, 128); |
1148 | case V4L2_CID_HUE: | 1209 | case V4L2_CID_HUE: |
1149 | return v4l2_ctrl_query_fill(qc, -180, 180, 5, 0); | 1210 | return v4l2_ctrl_query_fill(qc, -180, 180, 5, 0); |
1211 | case V4L2_CID_GAIN: | ||
1212 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128); | ||
1213 | case V4L2_CID_AUTOGAIN: | ||
1214 | return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); | ||
1150 | } | 1215 | } |
1151 | return -EINVAL; | 1216 | return -EINVAL; |
1152 | } | 1217 | } |
@@ -1166,6 +1231,10 @@ static int ov7670_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
1166 | return ov7670_g_vflip(sd, &ctrl->value); | 1231 | return ov7670_g_vflip(sd, &ctrl->value); |
1167 | case V4L2_CID_HFLIP: | 1232 | case V4L2_CID_HFLIP: |
1168 | return ov7670_g_hflip(sd, &ctrl->value); | 1233 | return ov7670_g_hflip(sd, &ctrl->value); |
1234 | case V4L2_CID_GAIN: | ||
1235 | return ov7670_g_gain(sd, &ctrl->value); | ||
1236 | case V4L2_CID_AUTOGAIN: | ||
1237 | return ov7670_g_autogain(sd, &ctrl->value); | ||
1169 | } | 1238 | } |
1170 | return -EINVAL; | 1239 | return -EINVAL; |
1171 | } | 1240 | } |
@@ -1185,6 +1254,10 @@ static int ov7670_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) | |||
1185 | return ov7670_s_vflip(sd, ctrl->value); | 1254 | return ov7670_s_vflip(sd, ctrl->value); |
1186 | case V4L2_CID_HFLIP: | 1255 | case V4L2_CID_HFLIP: |
1187 | return ov7670_s_hflip(sd, ctrl->value); | 1256 | return ov7670_s_hflip(sd, ctrl->value); |
1257 | case V4L2_CID_GAIN: | ||
1258 | return ov7670_s_gain(sd, ctrl->value); | ||
1259 | case V4L2_CID_AUTOGAIN: | ||
1260 | return ov7670_s_autogain(sd, ctrl->value); | ||
1188 | } | 1261 | } |
1189 | return -EINVAL; | 1262 | return -EINVAL; |
1190 | } | 1263 | } |