aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean-François Moine <moinejf@free.fr>2011-03-13 15:36:49 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-22 03:54:49 -0400
commit58c92d37e7d34433cfbc3989bec20e48fba0799e (patch)
tree4caccbda16d5f5dcceeb5a924c64f1359ad07650
parent7d47b789ceb456d90a3ace522dbcb2a94d2693ca (diff)
[media] gspca - ov519: Add exposure and autogain controls for ov2610/2610ae
Signed-off-by: Jean-François Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/gspca/ov519.c120
1 files changed, 106 insertions, 14 deletions
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 42670ec7ef3b..fd1b6082c96d 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -1,7 +1,7 @@
1/** 1/**
2 * OV519 driver 2 * OV519 driver
3 * 3 *
4 * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr) 4 * Copyright (C) 2008-2011 Jean-François Moine <moinejf@free.fr>
5 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> 5 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
6 * 6 *
7 * This module is adapted from the ov51x-jpeg package, which itself 7 * This module is adapted from the ov51x-jpeg package, which itself
@@ -61,10 +61,12 @@ static int i2c_detect_tries = 10;
61enum e_ctrl { 61enum e_ctrl {
62 BRIGHTNESS, 62 BRIGHTNESS,
63 CONTRAST, 63 CONTRAST,
64 EXPOSURE,
64 COLORS, 65 COLORS,
65 HFLIP, 66 HFLIP,
66 VFLIP, 67 VFLIP,
67 AUTOBRIGHT, 68 AUTOBRIGHT,
69 AUTOGAIN,
68 FREQ, 70 FREQ,
69 NCTRL /* number of controls */ 71 NCTRL /* number of controls */
70}; 72};
@@ -142,9 +144,11 @@ enum sensors {
142/* V4L2 controls supported by the driver */ 144/* V4L2 controls supported by the driver */
143static void setbrightness(struct gspca_dev *gspca_dev); 145static void setbrightness(struct gspca_dev *gspca_dev);
144static void setcontrast(struct gspca_dev *gspca_dev); 146static void setcontrast(struct gspca_dev *gspca_dev);
147static void setexposure(struct gspca_dev *gspca_dev);
145static void setcolors(struct gspca_dev *gspca_dev); 148static void setcolors(struct gspca_dev *gspca_dev);
146static void sethvflip(struct gspca_dev *gspca_dev); 149static void sethvflip(struct gspca_dev *gspca_dev);
147static void setautobright(struct gspca_dev *gspca_dev); 150static void setautobright(struct gspca_dev *gspca_dev);
151static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
148static void setfreq(struct gspca_dev *gspca_dev); 152static void setfreq(struct gspca_dev *gspca_dev);
149static void setfreq_i(struct sd *sd); 153static void setfreq_i(struct sd *sd);
150 154
@@ -173,6 +177,18 @@ static const struct ctrl sd_ctrls[] = {
173 }, 177 },
174 .set_control = setcontrast, 178 .set_control = setcontrast,
175 }, 179 },
180[EXPOSURE] = {
181 {
182 .id = V4L2_CID_EXPOSURE,
183 .type = V4L2_CTRL_TYPE_INTEGER,
184 .name = "Exposure",
185 .minimum = 0,
186 .maximum = 255,
187 .step = 1,
188 .default_value = 127,
189 },
190 .set_control = setexposure,
191 },
176[COLORS] = { 192[COLORS] = {
177 { 193 {
178 .id = V4L2_CID_SATURATION, 194 .id = V4L2_CID_SATURATION,
@@ -222,6 +238,19 @@ static const struct ctrl sd_ctrls[] = {
222 }, 238 },
223 .set_control = setautobright, 239 .set_control = setautobright,
224 }, 240 },
241[AUTOGAIN] = {
242 {
243 .id = V4L2_CID_AUTOGAIN,
244 .type = V4L2_CTRL_TYPE_BOOLEAN,
245 .name = "Auto Gain",
246 .minimum = 0,
247 .maximum = 1,
248 .step = 1,
249 .default_value = 1,
250 .flags = V4L2_CTRL_FLAG_UPDATE
251 },
252 .set = sd_setautogain,
253 },
225[FREQ] = { 254[FREQ] = {
226 { 255 {
227 .id = V4L2_CID_POWER_LINE_FREQUENCY, 256 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -238,50 +267,78 @@ static const struct ctrl sd_ctrls[] = {
238 267
239/* table of the disabled controls */ 268/* table of the disabled controls */
240static const unsigned ctrl_dis[] = { 269static const unsigned ctrl_dis[] = {
241[SEN_OV2610] = (1 << NCTRL) - 1, /* no control */ 270[SEN_OV2610] = ((1 << NCTRL) - 1) /* no control */
271 ^ ((1 << EXPOSURE) /* but exposure */
272 | (1 << AUTOGAIN)), /* and autogain */
242 273
243[SEN_OV2610AE] = (1 << NCTRL) - 1, /* no control */ 274[SEN_OV2610AE] = ((1 << NCTRL) - 1) /* no control */
275 ^ ((1 << EXPOSURE) /* but exposure */
276 | (1 << AUTOGAIN)), /* and autogain */
244 277
245[SEN_OV3610] = (1 << NCTRL) - 1, /* no control */ 278[SEN_OV3610] = (1 << NCTRL) - 1, /* no control */
246 279
247[SEN_OV6620] = (1 << HFLIP) | 280[SEN_OV6620] = (1 << HFLIP) |
248 (1 << VFLIP), 281 (1 << VFLIP) |
282 (1 << EXPOSURE) |
283 (1 << AUTOGAIN),
249 284
250[SEN_OV6630] = (1 << HFLIP) | 285[SEN_OV6630] = (1 << HFLIP) |
251 (1 << VFLIP), 286 (1 << VFLIP) |
287 (1 << EXPOSURE) |
288 (1 << AUTOGAIN),
252 289
253[SEN_OV66308AF] = (1 << HFLIP) | 290[SEN_OV66308AF] = (1 << HFLIP) |
254 (1 << VFLIP), 291 (1 << VFLIP) |
292 (1 << EXPOSURE) |
293 (1 << AUTOGAIN),
255 294
256[SEN_OV7610] = (1 << HFLIP) | 295[SEN_OV7610] = (1 << HFLIP) |
257 (1 << VFLIP), 296 (1 << VFLIP) |
297 (1 << EXPOSURE) |
298 (1 << AUTOGAIN),
258 299
259[SEN_OV7620] = (1 << HFLIP) | 300[SEN_OV7620] = (1 << HFLIP) |
260 (1 << VFLIP), 301 (1 << VFLIP) |
302 (1 << EXPOSURE) |
303 (1 << AUTOGAIN),
261 304
262[SEN_OV7620AE] = (1 << HFLIP) | 305[SEN_OV7620AE] = (1 << HFLIP) |
263 (1 << VFLIP), 306 (1 << VFLIP) |
307 (1 << EXPOSURE) |
308 (1 << AUTOGAIN),
264 309
265[SEN_OV7640] = (1 << HFLIP) | 310[SEN_OV7640] = (1 << HFLIP) |
266 (1 << VFLIP) | 311 (1 << VFLIP) |
267 (1 << AUTOBRIGHT) | 312 (1 << AUTOBRIGHT) |
268 (1 << CONTRAST), 313 (1 << CONTRAST) |
314 (1 << EXPOSURE) |
315 (1 << AUTOGAIN),
269 316
270[SEN_OV7648] = (1 << HFLIP) | 317[SEN_OV7648] = (1 << HFLIP) |
271 (1 << VFLIP) | 318 (1 << VFLIP) |
272 (1 << AUTOBRIGHT) | 319 (1 << AUTOBRIGHT) |
273 (1 << CONTRAST), 320 (1 << CONTRAST) |
321 (1 << EXPOSURE) |
322 (1 << AUTOGAIN),
274 323
275[SEN_OV7660] = (1 << AUTOBRIGHT), 324[SEN_OV7660] = (1 << AUTOBRIGHT) |
325 (1 << EXPOSURE) |
326 (1 << AUTOGAIN),
276 327
277[SEN_OV7670] = (1 << COLORS) | 328[SEN_OV7670] = (1 << COLORS) |
278 (1 << AUTOBRIGHT), 329 (1 << AUTOBRIGHT) |
330 (1 << EXPOSURE) |
331 (1 << AUTOGAIN),
279 332
280[SEN_OV76BE] = (1 << HFLIP) | 333[SEN_OV76BE] = (1 << HFLIP) |
281 (1 << VFLIP), 334 (1 << VFLIP) |
335 (1 << EXPOSURE) |
336 (1 << AUTOGAIN),
282 337
283[SEN_OV8610] = (1 << HFLIP) | 338[SEN_OV8610] = (1 << HFLIP) |
284 (1 << VFLIP) | 339 (1 << VFLIP) |
340 (1 << EXPOSURE) |
341 (1 << AUTOGAIN) |
285 (1 << FREQ), 342 (1 << FREQ),
286}; 343};
287 344
@@ -3201,6 +3258,13 @@ static void ov519_set_fr(struct sd *sd)
3201 ov518_i2c_w(sd, OV7670_R11_CLKRC, clock); 3258 ov518_i2c_w(sd, OV7670_R11_CLKRC, clock);
3202} 3259}
3203 3260
3261static void setautogain(struct gspca_dev *gspca_dev)
3262{
3263 struct sd *sd = (struct sd *) gspca_dev;
3264
3265 i2c_w_mask(sd, 0x13, sd->ctrls[AUTOGAIN].val ? 0x05 : 0x00, 0x05);
3266}
3267
3204/* this function is called at probe time */ 3268/* this function is called at probe time */
3205static int sd_config(struct gspca_dev *gspca_dev, 3269static int sd_config(struct gspca_dev *gspca_dev,
3206 const struct usb_device_id *id) 3270 const struct usb_device_id *id)
@@ -4189,12 +4253,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
4189 setcontrast(gspca_dev); 4253 setcontrast(gspca_dev);
4190 if (!(sd->gspca_dev.ctrl_dis & (1 << BRIGHTNESS))) 4254 if (!(sd->gspca_dev.ctrl_dis & (1 << BRIGHTNESS)))
4191 setbrightness(gspca_dev); 4255 setbrightness(gspca_dev);
4256 if (!(sd->gspca_dev.ctrl_dis & (1 << EXPOSURE)))
4257 setexposure(gspca_dev);
4192 if (!(sd->gspca_dev.ctrl_dis & (1 << COLORS))) 4258 if (!(sd->gspca_dev.ctrl_dis & (1 << COLORS)))
4193 setcolors(gspca_dev); 4259 setcolors(gspca_dev);
4194 if (!(sd->gspca_dev.ctrl_dis & ((1 << HFLIP) | (1 << VFLIP)))) 4260 if (!(sd->gspca_dev.ctrl_dis & ((1 << HFLIP) | (1 << VFLIP))))
4195 sethvflip(gspca_dev); 4261 sethvflip(gspca_dev);
4196 if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOBRIGHT))) 4262 if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOBRIGHT)))
4197 setautobright(gspca_dev); 4263 setautobright(gspca_dev);
4264 if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOGAIN)))
4265 setautogain(gspca_dev);
4198 if (!(sd->gspca_dev.ctrl_dis & (1 << FREQ))) 4266 if (!(sd->gspca_dev.ctrl_dis & (1 << FREQ)))
4199 setfreq_i(sd); 4267 setfreq_i(sd);
4200 4268
@@ -4608,6 +4676,14 @@ static void setcontrast(struct gspca_dev *gspca_dev)
4608 } 4676 }
4609} 4677}
4610 4678
4679static void setexposure(struct gspca_dev *gspca_dev)
4680{
4681 struct sd *sd = (struct sd *) gspca_dev;
4682
4683 if (!sd->ctrls[AUTOGAIN].val)
4684 i2c_w(sd, 0x10, sd->ctrls[EXPOSURE].val);
4685}
4686
4611static void setcolors(struct gspca_dev *gspca_dev) 4687static void setcolors(struct gspca_dev *gspca_dev)
4612{ 4688{
4613 struct sd *sd = (struct sd *) gspca_dev; 4689 struct sd *sd = (struct sd *) gspca_dev;
@@ -4666,6 +4742,22 @@ static void setautobright(struct gspca_dev *gspca_dev)
4666 i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10); 4742 i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10);
4667} 4743}
4668 4744
4745static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
4746{
4747 struct sd *sd = (struct sd *) gspca_dev;
4748
4749 sd->ctrls[AUTOGAIN].val = val;
4750 if (val) {
4751 gspca_dev->ctrl_inac |= (1 << EXPOSURE);
4752 } else {
4753 gspca_dev->ctrl_inac &= ~(1 << EXPOSURE);
4754 sd->ctrls[EXPOSURE].val = i2c_r(sd, 0x10);
4755 }
4756 if (gspca_dev->streaming)
4757 setautogain(gspca_dev);
4758 return gspca_dev->usb_err;
4759}
4760
4669static void setfreq_i(struct sd *sd) 4761static void setfreq_i(struct sd *sd)
4670{ 4762{
4671 if (sd->sensor == SEN_OV7660 4763 if (sd->sensor == SEN_OV7660