aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2012-05-16 05:19:46 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-07-30 17:25:24 -0400
commitcf9211e85e656731bef4f373df42339ba88ef956 (patch)
tree855dd3e28b02e6c9a26fa862781cccee3543b191 /drivers/media/video/gspca
parenta17dd1ebd5396e929c10c60237a1fab5adae57cf (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.c599
-rw-r--r--drivers/media/video/gspca/w996Xcf.c15
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..." */
61static int i2c_detect_tries = 10; 61static int i2c_detect_tries = 10;
62 62
63/* controls */
64enum 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 */
78struct sd { 64struct 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 */
149static void setbrightness(struct gspca_dev *gspca_dev); 143struct ctrl_valid {
150static void setcontrast(struct gspca_dev *gspca_dev); 144 int has_brightness:1;
151static void setexposure(struct gspca_dev *gspca_dev); 145 int has_contrast:1;
152static void setcolors(struct gspca_dev *gspca_dev); 146 int has_exposure:1;
153static void sethvflip(struct gspca_dev *gspca_dev); 147 int has_autogain:1;
154static void setautobright(struct gspca_dev *gspca_dev); 148 int has_sat:1;
155static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 149 int has_hvflip:1;
156static void setfreq(struct gspca_dev *gspca_dev); 150 int has_autobright:1;
157static void setfreq_i(struct sd *sd); 151 int has_freq:1;
158 152};
159static const struct ctrl sd_ctrls[] = { 153
160[BRIGHTNESS] = { 154static 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 */
273static 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
353static const struct v4l2_pix_format ov519_vga_mode[] = { 250static 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
3309static void setautogain(struct gspca_dev *gspca_dev) 3206static 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 */
4180static void sethvflip(struct gspca_dev *gspca_dev) 4057static 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
4608static void setbrightness(struct gspca_dev *gspca_dev) 4469static 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
4659static void setcontrast(struct gspca_dev *gspca_dev) 4516static 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
4763static void setexposure(struct gspca_dev *gspca_dev) 4618static 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
4771static void setcolors(struct gspca_dev *gspca_dev) 4625static 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
4822static void setautobright(struct gspca_dev *gspca_dev) 4674static 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
4829static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) 4681static 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
4845static 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}
4903static void setfreq(struct gspca_dev *gspca_dev) 4739
4740static 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
4914static 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
4943static int sd_get_jcomp(struct gspca_dev *gspca_dev, 4751static 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) 4778static 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
4794static 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 */ 4839static 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
4844static 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 */
4983static const struct sd_desc sd_desc = { 4916static 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
515static void w9968cf_stop0(struct sd *sd) 521static 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}