diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2012-05-16 05:19:46 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-07-30 17:25:24 -0400 |
commit | cf9211e85e656731bef4f373df42339ba88ef956 (patch) | |
tree | 855dd3e28b02e6c9a26fa862781cccee3543b191 /drivers/media/video/gspca | |
parent | a17dd1ebd5396e929c10c60237a1fab5adae57cf (diff) |
[media] ov519: convert to the control framework
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca')
-rw-r--r-- | drivers/media/video/gspca/ov519.c | 599 | ||||
-rw-r--r-- | drivers/media/video/gspca/w996Xcf.c | 15 |
2 files changed, 276 insertions, 338 deletions
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c index 183457c5cfdb..35fa141945c0 100644 --- a/drivers/media/video/gspca/ov519.c +++ b/drivers/media/video/gspca/ov519.c | |||
@@ -60,25 +60,20 @@ static int frame_rate; | |||
60 | * are getting "Failed to read sensor ID..." */ | 60 | * are getting "Failed to read sensor ID..." */ |
61 | static int i2c_detect_tries = 10; | 61 | static int i2c_detect_tries = 10; |
62 | 62 | ||
63 | /* controls */ | ||
64 | enum e_ctrl { | ||
65 | BRIGHTNESS, | ||
66 | CONTRAST, | ||
67 | EXPOSURE, | ||
68 | COLORS, | ||
69 | HFLIP, | ||
70 | VFLIP, | ||
71 | AUTOBRIGHT, | ||
72 | AUTOGAIN, | ||
73 | FREQ, | ||
74 | NCTRL /* number of controls */ | ||
75 | }; | ||
76 | |||
77 | /* ov519 device descriptor */ | 63 | /* ov519 device descriptor */ |
78 | struct sd { | 64 | struct sd { |
79 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 65 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
80 | 66 | ||
81 | struct gspca_ctrl ctrls[NCTRL]; | 67 | struct v4l2_ctrl *jpegqual; |
68 | struct v4l2_ctrl *freq; | ||
69 | struct { /* h/vflip control cluster */ | ||
70 | struct v4l2_ctrl *hflip; | ||
71 | struct v4l2_ctrl *vflip; | ||
72 | }; | ||
73 | struct { /* autobrightness/brightness control cluster */ | ||
74 | struct v4l2_ctrl *autobright; | ||
75 | struct v4l2_ctrl *brightness; | ||
76 | }; | ||
82 | 77 | ||
83 | u8 packet_nr; | 78 | u8 packet_nr; |
84 | 79 | ||
@@ -101,7 +96,6 @@ struct sd { | |||
101 | /* Determined by sensor type */ | 96 | /* Determined by sensor type */ |
102 | u8 sif; | 97 | u8 sif; |
103 | 98 | ||
104 | u8 quality; | ||
105 | #define QUALITY_MIN 50 | 99 | #define QUALITY_MIN 50 |
106 | #define QUALITY_MAX 70 | 100 | #define QUALITY_MAX 70 |
107 | #define QUALITY_DEF 50 | 101 | #define QUALITY_DEF 50 |
@@ -145,209 +139,112 @@ enum sensors { | |||
145 | really should move the sensor drivers to v4l2 sub drivers. */ | 139 | really should move the sensor drivers to v4l2 sub drivers. */ |
146 | #include "w996Xcf.c" | 140 | #include "w996Xcf.c" |
147 | 141 | ||
148 | /* V4L2 controls supported by the driver */ | 142 | /* table of the disabled controls */ |
149 | static void setbrightness(struct gspca_dev *gspca_dev); | 143 | struct ctrl_valid { |
150 | static void setcontrast(struct gspca_dev *gspca_dev); | 144 | int has_brightness:1; |
151 | static void setexposure(struct gspca_dev *gspca_dev); | 145 | int has_contrast:1; |
152 | static void setcolors(struct gspca_dev *gspca_dev); | 146 | int has_exposure:1; |
153 | static void sethvflip(struct gspca_dev *gspca_dev); | 147 | int has_autogain:1; |
154 | static void setautobright(struct gspca_dev *gspca_dev); | 148 | int has_sat:1; |
155 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); | 149 | int has_hvflip:1; |
156 | static void setfreq(struct gspca_dev *gspca_dev); | 150 | int has_autobright:1; |
157 | static void setfreq_i(struct sd *sd); | 151 | int has_freq:1; |
158 | 152 | }; | |
159 | static const struct ctrl sd_ctrls[] = { | 153 | |
160 | [BRIGHTNESS] = { | 154 | static const struct ctrl_valid valid_controls[] = { |
161 | { | 155 | [SEN_OV2610] = { |
162 | .id = V4L2_CID_BRIGHTNESS, | 156 | .has_exposure = 1, |
163 | .type = V4L2_CTRL_TYPE_INTEGER, | 157 | .has_autogain = 1, |
164 | .name = "Brightness", | ||
165 | .minimum = 0, | ||
166 | .maximum = 255, | ||
167 | .step = 1, | ||
168 | .default_value = 127, | ||
169 | }, | ||
170 | .set_control = setbrightness, | ||
171 | }, | 158 | }, |
172 | [CONTRAST] = { | 159 | [SEN_OV2610AE] = { |
173 | { | 160 | .has_exposure = 1, |
174 | .id = V4L2_CID_CONTRAST, | 161 | .has_autogain = 1, |
175 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
176 | .name = "Contrast", | ||
177 | .minimum = 0, | ||
178 | .maximum = 255, | ||
179 | .step = 1, | ||
180 | .default_value = 127, | ||
181 | }, | ||
182 | .set_control = setcontrast, | ||
183 | }, | 162 | }, |
184 | [EXPOSURE] = { | 163 | [SEN_OV3610] = { |
185 | { | 164 | /* No controls */ |
186 | .id = V4L2_CID_EXPOSURE, | ||
187 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
188 | .name = "Exposure", | ||
189 | .minimum = 0, | ||
190 | .maximum = 255, | ||
191 | .step = 1, | ||
192 | .default_value = 127, | ||
193 | }, | ||
194 | .set_control = setexposure, | ||
195 | }, | 165 | }, |
196 | [COLORS] = { | 166 | [SEN_OV6620] = { |
197 | { | 167 | .has_brightness = 1, |
198 | .id = V4L2_CID_SATURATION, | 168 | .has_contrast = 1, |
199 | .type = V4L2_CTRL_TYPE_INTEGER, | 169 | .has_sat = 1, |
200 | .name = "Color", | 170 | .has_autobright = 1, |
201 | .minimum = 0, | 171 | .has_freq = 1, |
202 | .maximum = 255, | ||
203 | .step = 1, | ||
204 | .default_value = 127, | ||
205 | }, | ||
206 | .set_control = setcolors, | ||
207 | }, | 172 | }, |
208 | /* The flip controls work for sensors ov7660 and ov7670 only */ | 173 | [SEN_OV6630] = { |
209 | [HFLIP] = { | 174 | .has_brightness = 1, |
210 | { | 175 | .has_contrast = 1, |
211 | .id = V4L2_CID_HFLIP, | 176 | .has_sat = 1, |
212 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 177 | .has_autobright = 1, |
213 | .name = "Mirror", | 178 | .has_freq = 1, |
214 | .minimum = 0, | ||
215 | .maximum = 1, | ||
216 | .step = 1, | ||
217 | .default_value = 0, | ||
218 | }, | ||
219 | .set_control = sethvflip, | ||
220 | }, | 179 | }, |
221 | [VFLIP] = { | 180 | [SEN_OV66308AF] = { |
222 | { | 181 | .has_brightness = 1, |
223 | .id = V4L2_CID_VFLIP, | 182 | .has_contrast = 1, |
224 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 183 | .has_sat = 1, |
225 | .name = "Vflip", | 184 | .has_autobright = 1, |
226 | .minimum = 0, | 185 | .has_freq = 1, |
227 | .maximum = 1, | ||
228 | .step = 1, | ||
229 | .default_value = 0, | ||
230 | }, | ||
231 | .set_control = sethvflip, | ||
232 | }, | 186 | }, |
233 | [AUTOBRIGHT] = { | 187 | [SEN_OV7610] = { |
234 | { | 188 | .has_brightness = 1, |
235 | .id = V4L2_CID_AUTOBRIGHTNESS, | 189 | .has_contrast = 1, |
236 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 190 | .has_sat = 1, |
237 | .name = "Auto Brightness", | 191 | .has_autobright = 1, |
238 | .minimum = 0, | 192 | .has_freq = 1, |
239 | .maximum = 1, | ||
240 | .step = 1, | ||
241 | .default_value = 1, | ||
242 | }, | ||
243 | .set_control = setautobright, | ||
244 | }, | 193 | }, |
245 | [AUTOGAIN] = { | 194 | [SEN_OV7620] = { |
246 | { | 195 | .has_brightness = 1, |
247 | .id = V4L2_CID_AUTOGAIN, | 196 | .has_contrast = 1, |
248 | .type = V4L2_CTRL_TYPE_BOOLEAN, | 197 | .has_sat = 1, |
249 | .name = "Auto Gain", | 198 | .has_autobright = 1, |
250 | .minimum = 0, | 199 | .has_freq = 1, |
251 | .maximum = 1, | ||
252 | .step = 1, | ||
253 | .default_value = 1, | ||
254 | .flags = V4L2_CTRL_FLAG_UPDATE | ||
255 | }, | ||
256 | .set = sd_setautogain, | ||
257 | }, | 200 | }, |
258 | [FREQ] = { | 201 | [SEN_OV7620AE] = { |
259 | { | 202 | .has_brightness = 1, |
260 | .id = V4L2_CID_POWER_LINE_FREQUENCY, | 203 | .has_contrast = 1, |
261 | .type = V4L2_CTRL_TYPE_MENU, | 204 | .has_sat = 1, |
262 | .name = "Light frequency filter", | 205 | .has_autobright = 1, |
263 | .minimum = 0, | 206 | .has_freq = 1, |
264 | .maximum = 2, /* 0: no flicker, 1: 50Hz, 2:60Hz, 3: auto */ | 207 | }, |
265 | .step = 1, | 208 | [SEN_OV7640] = { |
266 | .default_value = 0, | 209 | .has_brightness = 1, |
267 | }, | 210 | .has_sat = 1, |
268 | .set_control = setfreq, | 211 | .has_freq = 1, |
212 | }, | ||
213 | [SEN_OV7648] = { | ||
214 | .has_brightness = 1, | ||
215 | .has_sat = 1, | ||
216 | .has_freq = 1, | ||
217 | }, | ||
218 | [SEN_OV7660] = { | ||
219 | .has_brightness = 1, | ||
220 | .has_contrast = 1, | ||
221 | .has_sat = 1, | ||
222 | .has_hvflip = 1, | ||
223 | .has_freq = 1, | ||
224 | }, | ||
225 | [SEN_OV7670] = { | ||
226 | .has_brightness = 1, | ||
227 | .has_contrast = 1, | ||
228 | .has_hvflip = 1, | ||
229 | .has_freq = 1, | ||
230 | }, | ||
231 | [SEN_OV76BE] = { | ||
232 | .has_brightness = 1, | ||
233 | .has_contrast = 1, | ||
234 | .has_sat = 1, | ||
235 | .has_autobright = 1, | ||
236 | .has_freq = 1, | ||
237 | }, | ||
238 | [SEN_OV8610] = { | ||
239 | .has_brightness = 1, | ||
240 | .has_contrast = 1, | ||
241 | .has_sat = 1, | ||
242 | .has_autobright = 1, | ||
243 | }, | ||
244 | [SEN_OV9600] = { | ||
245 | .has_exposure = 1, | ||
246 | .has_autogain = 1, | ||
269 | }, | 247 | }, |
270 | }; | ||
271 | |||
272 | /* table of the disabled controls */ | ||
273 | static const unsigned ctrl_dis[] = { | ||
274 | [SEN_OV2610] = ((1 << NCTRL) - 1) /* no control */ | ||
275 | ^ ((1 << EXPOSURE) /* but exposure */ | ||
276 | | (1 << AUTOGAIN)), /* and autogain */ | ||
277 | |||
278 | [SEN_OV2610AE] = ((1 << NCTRL) - 1) /* no control */ | ||
279 | ^ ((1 << EXPOSURE) /* but exposure */ | ||
280 | | (1 << AUTOGAIN)), /* and autogain */ | ||
281 | |||
282 | [SEN_OV3610] = (1 << NCTRL) - 1, /* no control */ | ||
283 | |||
284 | [SEN_OV6620] = (1 << HFLIP) | | ||
285 | (1 << VFLIP) | | ||
286 | (1 << EXPOSURE) | | ||
287 | (1 << AUTOGAIN), | ||
288 | |||
289 | [SEN_OV6630] = (1 << HFLIP) | | ||
290 | (1 << VFLIP) | | ||
291 | (1 << EXPOSURE) | | ||
292 | (1 << AUTOGAIN), | ||
293 | |||
294 | [SEN_OV66308AF] = (1 << HFLIP) | | ||
295 | (1 << VFLIP) | | ||
296 | (1 << EXPOSURE) | | ||
297 | (1 << AUTOGAIN), | ||
298 | |||
299 | [SEN_OV7610] = (1 << HFLIP) | | ||
300 | (1 << VFLIP) | | ||
301 | (1 << EXPOSURE) | | ||
302 | (1 << AUTOGAIN), | ||
303 | |||
304 | [SEN_OV7620] = (1 << HFLIP) | | ||
305 | (1 << VFLIP) | | ||
306 | (1 << EXPOSURE) | | ||
307 | (1 << AUTOGAIN), | ||
308 | |||
309 | [SEN_OV7620AE] = (1 << HFLIP) | | ||
310 | (1 << VFLIP) | | ||
311 | (1 << EXPOSURE) | | ||
312 | (1 << AUTOGAIN), | ||
313 | |||
314 | [SEN_OV7640] = (1 << HFLIP) | | ||
315 | (1 << VFLIP) | | ||
316 | (1 << AUTOBRIGHT) | | ||
317 | (1 << CONTRAST) | | ||
318 | (1 << EXPOSURE) | | ||
319 | (1 << AUTOGAIN), | ||
320 | |||
321 | [SEN_OV7648] = (1 << HFLIP) | | ||
322 | (1 << VFLIP) | | ||
323 | (1 << AUTOBRIGHT) | | ||
324 | (1 << CONTRAST) | | ||
325 | (1 << EXPOSURE) | | ||
326 | (1 << AUTOGAIN), | ||
327 | |||
328 | [SEN_OV7660] = (1 << AUTOBRIGHT) | | ||
329 | (1 << EXPOSURE) | | ||
330 | (1 << AUTOGAIN), | ||
331 | |||
332 | [SEN_OV7670] = (1 << COLORS) | | ||
333 | (1 << AUTOBRIGHT) | | ||
334 | (1 << EXPOSURE) | | ||
335 | (1 << AUTOGAIN), | ||
336 | |||
337 | [SEN_OV76BE] = (1 << HFLIP) | | ||
338 | (1 << VFLIP) | | ||
339 | (1 << EXPOSURE) | | ||
340 | (1 << AUTOGAIN), | ||
341 | |||
342 | [SEN_OV8610] = (1 << HFLIP) | | ||
343 | (1 << VFLIP) | | ||
344 | (1 << EXPOSURE) | | ||
345 | (1 << AUTOGAIN) | | ||
346 | (1 << FREQ), | ||
347 | [SEN_OV9600] = ((1 << NCTRL) - 1) /* no control */ | ||
348 | ^ ((1 << EXPOSURE) /* but exposure */ | ||
349 | | (1 << AUTOGAIN)), /* and autogain */ | ||
350 | |||
351 | }; | 248 | }; |
352 | 249 | ||
353 | static const struct v4l2_pix_format ov519_vga_mode[] = { | 250 | static const struct v4l2_pix_format ov519_vga_mode[] = { |
@@ -3306,11 +3203,11 @@ static void ov519_set_fr(struct sd *sd) | |||
3306 | ov518_i2c_w(sd, OV7670_R11_CLKRC, clock); | 3203 | ov518_i2c_w(sd, OV7670_R11_CLKRC, clock); |
3307 | } | 3204 | } |
3308 | 3205 | ||
3309 | static void setautogain(struct gspca_dev *gspca_dev) | 3206 | static void setautogain(struct gspca_dev *gspca_dev, s32 val) |
3310 | { | 3207 | { |
3311 | struct sd *sd = (struct sd *) gspca_dev; | 3208 | struct sd *sd = (struct sd *) gspca_dev; |
3312 | 3209 | ||
3313 | i2c_w_mask(sd, 0x13, sd->ctrls[AUTOGAIN].val ? 0x05 : 0x00, 0x05); | 3210 | i2c_w_mask(sd, 0x13, val ? 0x05 : 0x00, 0x05); |
3314 | } | 3211 | } |
3315 | 3212 | ||
3316 | /* this function is called at probe time */ | 3213 | /* this function is called at probe time */ |
@@ -3351,8 +3248,6 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
3351 | break; | 3248 | break; |
3352 | } | 3249 | } |
3353 | 3250 | ||
3354 | gspca_dev->cam.ctrls = sd->ctrls; | ||
3355 | sd->quality = QUALITY_DEF; | ||
3356 | sd->frame_rate = 15; | 3251 | sd->frame_rate = 15; |
3357 | 3252 | ||
3358 | return 0; | 3253 | return 0; |
@@ -3467,8 +3362,6 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
3467 | break; | 3362 | break; |
3468 | } | 3363 | } |
3469 | 3364 | ||
3470 | gspca_dev->ctrl_dis = ctrl_dis[sd->sensor]; | ||
3471 | |||
3472 | /* initialize the sensor */ | 3365 | /* initialize the sensor */ |
3473 | switch (sd->sensor) { | 3366 | switch (sd->sensor) { |
3474 | case SEN_OV2610: | 3367 | case SEN_OV2610: |
@@ -3494,8 +3387,6 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
3494 | break; | 3387 | break; |
3495 | case SEN_OV6630: | 3388 | case SEN_OV6630: |
3496 | case SEN_OV66308AF: | 3389 | case SEN_OV66308AF: |
3497 | sd->ctrls[CONTRAST].def = 200; | ||
3498 | /* The default is too low for the ov6630 */ | ||
3499 | write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)); | 3390 | write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)); |
3500 | break; | 3391 | break; |
3501 | default: | 3392 | default: |
@@ -3522,26 +3413,12 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
3522 | sd->gspca_dev.curr_mode = 1; /* 640x480 */ | 3413 | sd->gspca_dev.curr_mode = 1; /* 640x480 */ |
3523 | ov519_set_mode(sd); | 3414 | ov519_set_mode(sd); |
3524 | ov519_set_fr(sd); | 3415 | ov519_set_fr(sd); |
3525 | sd->ctrls[COLORS].max = 4; /* 0..4 */ | ||
3526 | sd->ctrls[COLORS].val = | ||
3527 | sd->ctrls[COLORS].def = 2; | ||
3528 | setcolors(gspca_dev); | ||
3529 | sd->ctrls[CONTRAST].max = 6; /* 0..6 */ | ||
3530 | sd->ctrls[CONTRAST].val = | ||
3531 | sd->ctrls[CONTRAST].def = 3; | ||
3532 | setcontrast(gspca_dev); | ||
3533 | sd->ctrls[BRIGHTNESS].max = 6; /* 0..6 */ | ||
3534 | sd->ctrls[BRIGHTNESS].val = | ||
3535 | sd->ctrls[BRIGHTNESS].def = 3; | ||
3536 | setbrightness(gspca_dev); | ||
3537 | sd_reset_snapshot(gspca_dev); | 3416 | sd_reset_snapshot(gspca_dev); |
3538 | ov51x_restart(sd); | 3417 | ov51x_restart(sd); |
3539 | ov51x_stop(sd); /* not in win traces */ | 3418 | ov51x_stop(sd); /* not in win traces */ |
3540 | ov51x_led_control(sd, 0); | 3419 | ov51x_led_control(sd, 0); |
3541 | break; | 3420 | break; |
3542 | case SEN_OV7670: | 3421 | case SEN_OV7670: |
3543 | sd->ctrls[FREQ].max = 3; /* auto */ | ||
3544 | sd->ctrls[FREQ].def = 3; | ||
3545 | write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)); | 3422 | write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)); |
3546 | break; | 3423 | break; |
3547 | case SEN_OV8610: | 3424 | case SEN_OV8610: |
@@ -4177,15 +4054,14 @@ static void mode_init_ov_sensor_regs(struct sd *sd) | |||
4177 | } | 4054 | } |
4178 | 4055 | ||
4179 | /* this function works for bridge ov519 and sensors ov7660 and ov7670 only */ | 4056 | /* this function works for bridge ov519 and sensors ov7660 and ov7670 only */ |
4180 | static void sethvflip(struct gspca_dev *gspca_dev) | 4057 | static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip) |
4181 | { | 4058 | { |
4182 | struct sd *sd = (struct sd *) gspca_dev; | 4059 | struct sd *sd = (struct sd *) gspca_dev; |
4183 | 4060 | ||
4184 | if (sd->gspca_dev.streaming) | 4061 | if (sd->gspca_dev.streaming) |
4185 | reg_w(sd, OV519_R51_RESET1, 0x0f); /* block stream */ | 4062 | reg_w(sd, OV519_R51_RESET1, 0x0f); /* block stream */ |
4186 | i2c_w_mask(sd, OV7670_R1E_MVFP, | 4063 | i2c_w_mask(sd, OV7670_R1E_MVFP, |
4187 | OV7670_MVFP_MIRROR * sd->ctrls[HFLIP].val | 4064 | OV7670_MVFP_MIRROR * hflip | OV7670_MVFP_VFLIP * vflip, |
4188 | | OV7670_MVFP_VFLIP * sd->ctrls[VFLIP].val, | ||
4189 | OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP); | 4065 | OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP); |
4190 | if (sd->gspca_dev.streaming) | 4066 | if (sd->gspca_dev.streaming) |
4191 | reg_w(sd, OV519_R51_RESET1, 0x00); /* restart stream */ | 4067 | reg_w(sd, OV519_R51_RESET1, 0x00); /* restart stream */ |
@@ -4333,22 +4209,7 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
4333 | 4209 | ||
4334 | set_ov_sensor_window(sd); | 4210 | set_ov_sensor_window(sd); |
4335 | 4211 | ||
4336 | if (!(sd->gspca_dev.ctrl_dis & (1 << CONTRAST))) | 4212 | v4l2_ctrl_handler_setup(&gspca_dev->ctrl_handler); |
4337 | setcontrast(gspca_dev); | ||
4338 | if (!(sd->gspca_dev.ctrl_dis & (1 << BRIGHTNESS))) | ||
4339 | setbrightness(gspca_dev); | ||
4340 | if (!(sd->gspca_dev.ctrl_dis & (1 << EXPOSURE))) | ||
4341 | setexposure(gspca_dev); | ||
4342 | if (!(sd->gspca_dev.ctrl_dis & (1 << COLORS))) | ||
4343 | setcolors(gspca_dev); | ||
4344 | if (!(sd->gspca_dev.ctrl_dis & ((1 << HFLIP) | (1 << VFLIP)))) | ||
4345 | sethvflip(gspca_dev); | ||
4346 | if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOBRIGHT))) | ||
4347 | setautobright(gspca_dev); | ||
4348 | if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOGAIN))) | ||
4349 | setautogain(gspca_dev); | ||
4350 | if (!(sd->gspca_dev.ctrl_dis & (1 << FREQ))) | ||
4351 | setfreq_i(sd); | ||
4352 | 4213 | ||
4353 | /* Force clear snapshot state in case the snapshot button was | 4214 | /* Force clear snapshot state in case the snapshot button was |
4354 | pressed while we weren't streaming */ | 4215 | pressed while we weren't streaming */ |
@@ -4605,10 +4466,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, | |||
4605 | 4466 | ||
4606 | /* -- management routines -- */ | 4467 | /* -- management routines -- */ |
4607 | 4468 | ||
4608 | static void setbrightness(struct gspca_dev *gspca_dev) | 4469 | static void setbrightness(struct gspca_dev *gspca_dev, s32 val) |
4609 | { | 4470 | { |
4610 | struct sd *sd = (struct sd *) gspca_dev; | 4471 | struct sd *sd = (struct sd *) gspca_dev; |
4611 | int val; | ||
4612 | static const struct ov_i2c_regvals brit_7660[][7] = { | 4472 | static const struct ov_i2c_regvals brit_7660[][7] = { |
4613 | {{0x0f, 0x6a}, {0x24, 0x40}, {0x25, 0x2b}, {0x26, 0x90}, | 4473 | {{0x0f, 0x6a}, {0x24, 0x40}, {0x25, 0x2b}, {0x26, 0x90}, |
4614 | {0x27, 0xe0}, {0x28, 0xe0}, {0x2c, 0xe0}}, | 4474 | {0x27, 0xe0}, {0x28, 0xe0}, {0x2c, 0xe0}}, |
@@ -4626,7 +4486,6 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
4626 | {0x27, 0x60}, {0x28, 0x60}, {0x2c, 0x60}} | 4486 | {0x27, 0x60}, {0x28, 0x60}, {0x2c, 0x60}} |
4627 | }; | 4487 | }; |
4628 | 4488 | ||
4629 | val = sd->ctrls[BRIGHTNESS].val; | ||
4630 | switch (sd->sensor) { | 4489 | switch (sd->sensor) { |
4631 | case SEN_OV8610: | 4490 | case SEN_OV8610: |
4632 | case SEN_OV7610: | 4491 | case SEN_OV7610: |
@@ -4640,9 +4499,7 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
4640 | break; | 4499 | break; |
4641 | case SEN_OV7620: | 4500 | case SEN_OV7620: |
4642 | case SEN_OV7620AE: | 4501 | case SEN_OV7620AE: |
4643 | /* 7620 doesn't like manual changes when in auto mode */ | 4502 | i2c_w(sd, OV7610_REG_BRT, val); |
4644 | if (!sd->ctrls[AUTOBRIGHT].val) | ||
4645 | i2c_w(sd, OV7610_REG_BRT, val); | ||
4646 | break; | 4503 | break; |
4647 | case SEN_OV7660: | 4504 | case SEN_OV7660: |
4648 | write_i2c_regvals(sd, brit_7660[val], | 4505 | write_i2c_regvals(sd, brit_7660[val], |
@@ -4656,10 +4513,9 @@ static void setbrightness(struct gspca_dev *gspca_dev) | |||
4656 | } | 4513 | } |
4657 | } | 4514 | } |
4658 | 4515 | ||
4659 | static void setcontrast(struct gspca_dev *gspca_dev) | 4516 | static void setcontrast(struct gspca_dev *gspca_dev, s32 val) |
4660 | { | 4517 | { |
4661 | struct sd *sd = (struct sd *) gspca_dev; | 4518 | struct sd *sd = (struct sd *) gspca_dev; |
4662 | int val; | ||
4663 | static const struct ov_i2c_regvals contrast_7660[][31] = { | 4519 | static const struct ov_i2c_regvals contrast_7660[][31] = { |
4664 | {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0xa0}, | 4520 | {{0x6c, 0xf0}, {0x6d, 0xf0}, {0x6e, 0xf8}, {0x6f, 0xa0}, |
4665 | {0x70, 0x58}, {0x71, 0x38}, {0x72, 0x30}, {0x73, 0x30}, | 4521 | {0x70, 0x58}, {0x71, 0x38}, {0x72, 0x30}, {0x73, 0x30}, |
@@ -4719,7 +4575,6 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
4719 | {0x88, 0xf1}, {0x89, 0xf9}, {0x8a, 0xfd}}, | 4575 | {0x88, 0xf1}, {0x89, 0xf9}, {0x8a, 0xfd}}, |
4720 | }; | 4576 | }; |
4721 | 4577 | ||
4722 | val = sd->ctrls[CONTRAST].val; | ||
4723 | switch (sd->sensor) { | 4578 | switch (sd->sensor) { |
4724 | case SEN_OV7610: | 4579 | case SEN_OV7610: |
4725 | case SEN_OV6620: | 4580 | case SEN_OV6620: |
@@ -4760,18 +4615,16 @@ static void setcontrast(struct gspca_dev *gspca_dev) | |||
4760 | } | 4615 | } |
4761 | } | 4616 | } |
4762 | 4617 | ||
4763 | static void setexposure(struct gspca_dev *gspca_dev) | 4618 | static void setexposure(struct gspca_dev *gspca_dev, s32 val) |
4764 | { | 4619 | { |
4765 | struct sd *sd = (struct sd *) gspca_dev; | 4620 | struct sd *sd = (struct sd *) gspca_dev; |
4766 | 4621 | ||
4767 | if (!sd->ctrls[AUTOGAIN].val) | 4622 | i2c_w(sd, 0x10, val); |
4768 | i2c_w(sd, 0x10, sd->ctrls[EXPOSURE].val); | ||
4769 | } | 4623 | } |
4770 | 4624 | ||
4771 | static void setcolors(struct gspca_dev *gspca_dev) | 4625 | static void setcolors(struct gspca_dev *gspca_dev, s32 val) |
4772 | { | 4626 | { |
4773 | struct sd *sd = (struct sd *) gspca_dev; | 4627 | struct sd *sd = (struct sd *) gspca_dev; |
4774 | int val; | ||
4775 | static const struct ov_i2c_regvals colors_7660[][6] = { | 4628 | static const struct ov_i2c_regvals colors_7660[][6] = { |
4776 | {{0x4f, 0x28}, {0x50, 0x2a}, {0x51, 0x02}, {0x52, 0x0a}, | 4629 | {{0x4f, 0x28}, {0x50, 0x2a}, {0x51, 0x02}, {0x52, 0x0a}, |
4777 | {0x53, 0x19}, {0x54, 0x23}}, | 4630 | {0x53, 0x19}, {0x54, 0x23}}, |
@@ -4785,7 +4638,6 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
4785 | {0x53, 0x66}, {0x54, 0x8e}}, | 4638 | {0x53, 0x66}, {0x54, 0x8e}}, |
4786 | }; | 4639 | }; |
4787 | 4640 | ||
4788 | val = sd->ctrls[COLORS].val; | ||
4789 | switch (sd->sensor) { | 4641 | switch (sd->sensor) { |
4790 | case SEN_OV8610: | 4642 | case SEN_OV8610: |
4791 | case SEN_OV7610: | 4643 | case SEN_OV7610: |
@@ -4819,34 +4671,18 @@ static void setcolors(struct gspca_dev *gspca_dev) | |||
4819 | } | 4671 | } |
4820 | } | 4672 | } |
4821 | 4673 | ||
4822 | static void setautobright(struct gspca_dev *gspca_dev) | 4674 | static void setautobright(struct gspca_dev *gspca_dev, s32 val) |
4823 | { | 4675 | { |
4824 | struct sd *sd = (struct sd *) gspca_dev; | 4676 | struct sd *sd = (struct sd *) gspca_dev; |
4825 | 4677 | ||
4826 | i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10); | 4678 | i2c_w_mask(sd, 0x2d, val ? 0x10 : 0x00, 0x10); |
4827 | } | 4679 | } |
4828 | 4680 | ||
4829 | static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) | 4681 | static void setfreq_i(struct sd *sd, s32 val) |
4830 | { | ||
4831 | struct sd *sd = (struct sd *) gspca_dev; | ||
4832 | |||
4833 | sd->ctrls[AUTOGAIN].val = val; | ||
4834 | if (val) { | ||
4835 | gspca_dev->ctrl_inac |= (1 << EXPOSURE); | ||
4836 | } else { | ||
4837 | gspca_dev->ctrl_inac &= ~(1 << EXPOSURE); | ||
4838 | sd->ctrls[EXPOSURE].val = i2c_r(sd, 0x10); | ||
4839 | } | ||
4840 | if (gspca_dev->streaming) | ||
4841 | setautogain(gspca_dev); | ||
4842 | return gspca_dev->usb_err; | ||
4843 | } | ||
4844 | |||
4845 | static void setfreq_i(struct sd *sd) | ||
4846 | { | 4682 | { |
4847 | if (sd->sensor == SEN_OV7660 | 4683 | if (sd->sensor == SEN_OV7660 |
4848 | || sd->sensor == SEN_OV7670) { | 4684 | || sd->sensor == SEN_OV7670) { |
4849 | switch (sd->ctrls[FREQ].val) { | 4685 | switch (val) { |
4850 | case 0: /* Banding filter disabled */ | 4686 | case 0: /* Banding filter disabled */ |
4851 | i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT); | 4687 | i2c_w_mask(sd, OV7670_R13_COM8, 0, OV7670_COM8_BFILT); |
4852 | break; | 4688 | break; |
@@ -4868,7 +4704,7 @@ static void setfreq_i(struct sd *sd) | |||
4868 | break; | 4704 | break; |
4869 | } | 4705 | } |
4870 | } else { | 4706 | } else { |
4871 | switch (sd->ctrls[FREQ].val) { | 4707 | switch (val) { |
4872 | case 0: /* Banding filter disabled */ | 4708 | case 0: /* Banding filter disabled */ |
4873 | i2c_w_mask(sd, 0x2d, 0x00, 0x04); | 4709 | i2c_w_mask(sd, 0x2d, 0x00, 0x04); |
4874 | i2c_w_mask(sd, 0x2a, 0x00, 0x80); | 4710 | i2c_w_mask(sd, 0x2a, 0x00, 0x80); |
@@ -4900,56 +4736,28 @@ static void setfreq_i(struct sd *sd) | |||
4900 | } | 4736 | } |
4901 | } | 4737 | } |
4902 | } | 4738 | } |
4903 | static void setfreq(struct gspca_dev *gspca_dev) | 4739 | |
4740 | static void setfreq(struct gspca_dev *gspca_dev, s32 val) | ||
4904 | { | 4741 | { |
4905 | struct sd *sd = (struct sd *) gspca_dev; | 4742 | struct sd *sd = (struct sd *) gspca_dev; |
4906 | 4743 | ||
4907 | setfreq_i(sd); | 4744 | setfreq_i(sd, val); |
4908 | 4745 | ||
4909 | /* Ugly but necessary */ | 4746 | /* Ugly but necessary */ |
4910 | if (sd->bridge == BRIDGE_W9968CF) | 4747 | if (sd->bridge == BRIDGE_W9968CF) |
4911 | w9968cf_set_crop_window(sd); | 4748 | w9968cf_set_crop_window(sd); |
4912 | } | 4749 | } |
4913 | 4750 | ||
4914 | static int sd_querymenu(struct gspca_dev *gspca_dev, | ||
4915 | struct v4l2_querymenu *menu) | ||
4916 | { | ||
4917 | struct sd *sd = (struct sd *) gspca_dev; | ||
4918 | |||
4919 | switch (menu->id) { | ||
4920 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
4921 | switch (menu->index) { | ||
4922 | case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */ | ||
4923 | strcpy((char *) menu->name, "NoFliker"); | ||
4924 | return 0; | ||
4925 | case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ | ||
4926 | strcpy((char *) menu->name, "50 Hz"); | ||
4927 | return 0; | ||
4928 | case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */ | ||
4929 | strcpy((char *) menu->name, "60 Hz"); | ||
4930 | return 0; | ||
4931 | case 3: | ||
4932 | if (sd->sensor != SEN_OV7670) | ||
4933 | return -EINVAL; | ||
4934 | |||
4935 | strcpy((char *) menu->name, "Automatic"); | ||
4936 | return 0; | ||
4937 | } | ||
4938 | break; | ||
4939 | } | ||
4940 | return -EINVAL; | ||
4941 | } | ||
4942 | |||
4943 | static int sd_get_jcomp(struct gspca_dev *gspca_dev, | 4751 | static int sd_get_jcomp(struct gspca_dev *gspca_dev, |
4944 | struct v4l2_jpegcompression *jcomp) | 4752 | struct v4l2_jpegcompression *jcomp) |
4945 | { | 4753 | { |
4946 | struct sd *sd = (struct sd *) gspca_dev; | 4754 | struct sd *sd = (struct sd *) gspca_dev; |
4947 | 4755 | ||
4948 | if (sd->bridge != BRIDGE_W9968CF) | 4756 | if (sd->bridge != BRIDGE_W9968CF) |
4949 | return -EINVAL; | 4757 | return -ENOTTY; |
4950 | 4758 | ||
4951 | memset(jcomp, 0, sizeof *jcomp); | 4759 | memset(jcomp, 0, sizeof *jcomp); |
4952 | jcomp->quality = sd->quality; | 4760 | jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual); |
4953 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT | | 4761 | jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT | V4L2_JPEG_MARKER_DQT | |
4954 | V4L2_JPEG_MARKER_DRI; | 4762 | V4L2_JPEG_MARKER_DRI; |
4955 | return 0; | 4763 | return 0; |
@@ -4961,38 +4769,161 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev, | |||
4961 | struct sd *sd = (struct sd *) gspca_dev; | 4769 | struct sd *sd = (struct sd *) gspca_dev; |
4962 | 4770 | ||
4963 | if (sd->bridge != BRIDGE_W9968CF) | 4771 | if (sd->bridge != BRIDGE_W9968CF) |
4964 | return -EINVAL; | 4772 | return -ENOTTY; |
4773 | |||
4774 | v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality); | ||
4775 | return 0; | ||
4776 | } | ||
4965 | 4777 | ||
4966 | if (gspca_dev->streaming) | 4778 | static int sd_g_volatile_ctrl(struct v4l2_ctrl *ctrl) |
4967 | return -EBUSY; | 4779 | { |
4780 | struct gspca_dev *gspca_dev = | ||
4781 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
4782 | struct sd *sd = (struct sd *)gspca_dev; | ||
4968 | 4783 | ||
4969 | if (jcomp->quality < QUALITY_MIN) | 4784 | gspca_dev->usb_err = 0; |
4970 | sd->quality = QUALITY_MIN; | 4785 | |
4971 | else if (jcomp->quality > QUALITY_MAX) | 4786 | switch (ctrl->id) { |
4972 | sd->quality = QUALITY_MAX; | 4787 | case V4L2_CID_AUTOGAIN: |
4973 | else | 4788 | gspca_dev->exposure->val = i2c_r(sd, 0x10); |
4974 | sd->quality = jcomp->quality; | 4789 | break; |
4790 | } | ||
4791 | return 0; | ||
4792 | } | ||
4793 | |||
4794 | static int sd_s_ctrl(struct v4l2_ctrl *ctrl) | ||
4795 | { | ||
4796 | struct gspca_dev *gspca_dev = | ||
4797 | container_of(ctrl->handler, struct gspca_dev, ctrl_handler); | ||
4798 | struct sd *sd = (struct sd *)gspca_dev; | ||
4799 | |||
4800 | gspca_dev->usb_err = 0; | ||
4801 | |||
4802 | if (!gspca_dev->streaming) | ||
4803 | return 0; | ||
4804 | |||
4805 | switch (ctrl->id) { | ||
4806 | case V4L2_CID_BRIGHTNESS: | ||
4807 | setbrightness(gspca_dev, ctrl->val); | ||
4808 | break; | ||
4809 | case V4L2_CID_CONTRAST: | ||
4810 | setcontrast(gspca_dev, ctrl->val); | ||
4811 | break; | ||
4812 | case V4L2_CID_POWER_LINE_FREQUENCY: | ||
4813 | setfreq(gspca_dev, ctrl->val); | ||
4814 | break; | ||
4815 | case V4L2_CID_AUTOBRIGHTNESS: | ||
4816 | if (ctrl->is_new) | ||
4817 | setautobright(gspca_dev, ctrl->val); | ||
4818 | if (!ctrl->val && sd->brightness->is_new) | ||
4819 | setbrightness(gspca_dev, sd->brightness->val); | ||
4820 | break; | ||
4821 | case V4L2_CID_SATURATION: | ||
4822 | setcolors(gspca_dev, ctrl->val); | ||
4823 | break; | ||
4824 | case V4L2_CID_HFLIP: | ||
4825 | sethvflip(gspca_dev, ctrl->val, sd->vflip->val); | ||
4826 | break; | ||
4827 | case V4L2_CID_AUTOGAIN: | ||
4828 | if (ctrl->is_new) | ||
4829 | setautogain(gspca_dev, ctrl->val); | ||
4830 | if (!ctrl->val && gspca_dev->exposure->is_new) | ||
4831 | setexposure(gspca_dev, gspca_dev->exposure->val); | ||
4832 | break; | ||
4833 | case V4L2_CID_JPEG_COMPRESSION_QUALITY: | ||
4834 | return -EBUSY; /* Should never happen, as we grab the ctrl */ | ||
4835 | } | ||
4836 | return gspca_dev->usb_err; | ||
4837 | } | ||
4975 | 4838 | ||
4976 | /* Return resulting jcomp params to app */ | 4839 | static const struct v4l2_ctrl_ops sd_ctrl_ops = { |
4977 | sd_get_jcomp(gspca_dev, jcomp); | 4840 | .g_volatile_ctrl = sd_g_volatile_ctrl, |
4841 | .s_ctrl = sd_s_ctrl, | ||
4842 | }; | ||
4843 | |||
4844 | static int sd_init_controls(struct gspca_dev *gspca_dev) | ||
4845 | { | ||
4846 | struct sd *sd = (struct sd *)gspca_dev; | ||
4847 | struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; | ||
4848 | |||
4849 | gspca_dev->vdev.ctrl_handler = hdl; | ||
4850 | v4l2_ctrl_handler_init(hdl, 10); | ||
4851 | if (valid_controls[sd->sensor].has_brightness) | ||
4852 | sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4853 | V4L2_CID_BRIGHTNESS, 0, | ||
4854 | sd->sensor == SEN_OV7660 ? 6 : 255, 1, | ||
4855 | sd->sensor == SEN_OV7660 ? 3 : 127); | ||
4856 | if (valid_controls[sd->sensor].has_contrast) { | ||
4857 | if (sd->sensor == SEN_OV7660) | ||
4858 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4859 | V4L2_CID_CONTRAST, 0, 6, 1, 3); | ||
4860 | else | ||
4861 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4862 | V4L2_CID_CONTRAST, 0, 255, 1, | ||
4863 | (sd->sensor == SEN_OV6630 || | ||
4864 | sd->sensor == SEN_OV66308AF) ? 200 : 127); | ||
4865 | } | ||
4866 | if (valid_controls[sd->sensor].has_sat) | ||
4867 | v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4868 | V4L2_CID_SATURATION, 0, | ||
4869 | sd->sensor == SEN_OV7660 ? 4 : 255, 1, | ||
4870 | sd->sensor == SEN_OV7660 ? 2 : 127); | ||
4871 | if (valid_controls[sd->sensor].has_exposure) | ||
4872 | gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4873 | V4L2_CID_EXPOSURE, 0, 255, 1, 127); | ||
4874 | if (valid_controls[sd->sensor].has_hvflip) { | ||
4875 | sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4876 | V4L2_CID_HFLIP, 0, 1, 1, 0); | ||
4877 | sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4878 | V4L2_CID_VFLIP, 0, 1, 1, 0); | ||
4879 | } | ||
4880 | if (valid_controls[sd->sensor].has_autobright) | ||
4881 | sd->autobright = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4882 | V4L2_CID_AUTOBRIGHTNESS, 0, 1, 1, 1); | ||
4883 | if (valid_controls[sd->sensor].has_autogain) | ||
4884 | gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4885 | V4L2_CID_AUTOGAIN, 0, 1, 1, 1); | ||
4886 | if (valid_controls[sd->sensor].has_freq) { | ||
4887 | if (sd->sensor == SEN_OV7670) | ||
4888 | sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, | ||
4889 | V4L2_CID_POWER_LINE_FREQUENCY, | ||
4890 | V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0, | ||
4891 | V4L2_CID_POWER_LINE_FREQUENCY_AUTO); | ||
4892 | else | ||
4893 | sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops, | ||
4894 | V4L2_CID_POWER_LINE_FREQUENCY, | ||
4895 | V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, 0); | ||
4896 | } | ||
4897 | if (sd->bridge == BRIDGE_W9968CF) | ||
4898 | sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, | ||
4899 | V4L2_CID_JPEG_COMPRESSION_QUALITY, | ||
4900 | QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF); | ||
4978 | 4901 | ||
4902 | if (hdl->error) { | ||
4903 | pr_err("Could not initialize controls\n"); | ||
4904 | return hdl->error; | ||
4905 | } | ||
4906 | if (gspca_dev->autogain) | ||
4907 | v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, true); | ||
4908 | if (sd->autobright) | ||
4909 | v4l2_ctrl_auto_cluster(2, &sd->autobright, 0, false); | ||
4910 | if (sd->hflip) | ||
4911 | v4l2_ctrl_cluster(2, &sd->hflip); | ||
4979 | return 0; | 4912 | return 0; |
4980 | } | 4913 | } |
4981 | 4914 | ||
4982 | /* sub-driver description */ | 4915 | /* sub-driver description */ |
4983 | static const struct sd_desc sd_desc = { | 4916 | static const struct sd_desc sd_desc = { |
4984 | .name = MODULE_NAME, | 4917 | .name = MODULE_NAME, |
4985 | .ctrls = sd_ctrls, | ||
4986 | .nctrls = ARRAY_SIZE(sd_ctrls), | ||
4987 | .config = sd_config, | 4918 | .config = sd_config, |
4988 | .init = sd_init, | 4919 | .init = sd_init, |
4920 | .init_controls = sd_init_controls, | ||
4989 | .isoc_init = sd_isoc_init, | 4921 | .isoc_init = sd_isoc_init, |
4990 | .start = sd_start, | 4922 | .start = sd_start, |
4991 | .stopN = sd_stopN, | 4923 | .stopN = sd_stopN, |
4992 | .stop0 = sd_stop0, | 4924 | .stop0 = sd_stop0, |
4993 | .pkt_scan = sd_pkt_scan, | 4925 | .pkt_scan = sd_pkt_scan, |
4994 | .dq_callback = sd_reset_snapshot, | 4926 | .dq_callback = sd_reset_snapshot, |
4995 | .querymenu = sd_querymenu, | ||
4996 | .get_jcomp = sd_get_jcomp, | 4927 | .get_jcomp = sd_get_jcomp, |
4997 | .set_jcomp = sd_set_jcomp, | 4928 | .set_jcomp = sd_set_jcomp, |
4998 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | 4929 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c index 27d2cef0692a..9e3a909e0a00 100644 --- a/drivers/media/video/gspca/w996Xcf.c +++ b/drivers/media/video/gspca/w996Xcf.c | |||
@@ -404,9 +404,14 @@ static void w9968cf_set_crop_window(struct sd *sd) | |||
404 | } | 404 | } |
405 | 405 | ||
406 | if (sd->sensor == SEN_OV7620) { | 406 | if (sd->sensor == SEN_OV7620) { |
407 | /* Sigh, this is dependend on the clock / framerate changes | 407 | /* |
408 | made by the frequency control, sick. */ | 408 | * Sigh, this is dependend on the clock / framerate changes |
409 | if (sd->ctrls[FREQ].val == 1) { | 409 | * made by the frequency control, sick. |
410 | * | ||
411 | * Note we cannot use v4l2_ctrl_g_ctrl here, as we get called | ||
412 | * from ov519.c:setfreq() with the ctrl lock held! | ||
413 | */ | ||
414 | if (sd->freq->val == 1) { | ||
410 | start_cropx = 277; | 415 | start_cropx = 277; |
411 | start_cropy = 37; | 416 | start_cropy = 37; |
412 | } else { | 417 | } else { |
@@ -474,8 +479,9 @@ static void w9968cf_mode_init_regs(struct sd *sd) | |||
474 | /* We may get called multiple times (usb isoc bw negotiat.) */ | 479 | /* We may get called multiple times (usb isoc bw negotiat.) */ |
475 | jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height, | 480 | jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height, |
476 | sd->gspca_dev.width, 0x22); /* JPEG 420 */ | 481 | sd->gspca_dev.width, 0x22); /* JPEG 420 */ |
477 | jpeg_set_qual(sd->jpeg_hdr, sd->quality); | 482 | jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual)); |
478 | w9968cf_upload_quantizationtables(sd); | 483 | w9968cf_upload_quantizationtables(sd); |
484 | v4l2_ctrl_grab(sd->jpegqual, true); | ||
479 | } | 485 | } |
480 | 486 | ||
481 | /* Video Capture Control Register */ | 487 | /* Video Capture Control Register */ |
@@ -514,6 +520,7 @@ static void w9968cf_mode_init_regs(struct sd *sd) | |||
514 | 520 | ||
515 | static void w9968cf_stop0(struct sd *sd) | 521 | static void w9968cf_stop0(struct sd *sd) |
516 | { | 522 | { |
523 | v4l2_ctrl_grab(sd->jpegqual, false); | ||
517 | reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */ | 524 | reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */ |
518 | reg_w(sd, 0x16, 0x0000); /* stop video capture */ | 525 | reg_w(sd, 0x16, 0x0000); /* stop video capture */ |
519 | } | 526 | } |