Commit 58c92d37 authored by Jean-François Moine's avatar Jean-François Moine Committed by Mauro Carvalho Chehab

[media] gspca - ov519: Add exposure and autogain controls for ov2610/2610ae

Signed-off-by: default avatarJean-François Moine <moinejf@free.fr>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 7d47b789
/** /**
* OV519 driver * OV519 driver
* *
* Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr) * Copyright (C) 2008-2011 Jean-François Moine <moinejf@free.fr>
* Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
* *
* This module is adapted from the ov51x-jpeg package, which itself * This module is adapted from the ov51x-jpeg package, which itself
...@@ -61,10 +61,12 @@ static int i2c_detect_tries = 10; ...@@ -61,10 +61,12 @@ static int i2c_detect_tries = 10;
enum e_ctrl { enum e_ctrl {
BRIGHTNESS, BRIGHTNESS,
CONTRAST, CONTRAST,
EXPOSURE,
COLORS, COLORS,
HFLIP, HFLIP,
VFLIP, VFLIP,
AUTOBRIGHT, AUTOBRIGHT,
AUTOGAIN,
FREQ, FREQ,
NCTRL /* number of controls */ NCTRL /* number of controls */
}; };
...@@ -142,9 +144,11 @@ enum sensors { ...@@ -142,9 +144,11 @@ enum sensors {
/* V4L2 controls supported by the driver */ /* V4L2 controls supported by the driver */
static void setbrightness(struct gspca_dev *gspca_dev); static void setbrightness(struct gspca_dev *gspca_dev);
static void setcontrast(struct gspca_dev *gspca_dev); static void setcontrast(struct gspca_dev *gspca_dev);
static void setexposure(struct gspca_dev *gspca_dev);
static void setcolors(struct gspca_dev *gspca_dev); static void setcolors(struct gspca_dev *gspca_dev);
static void sethvflip(struct gspca_dev *gspca_dev); static void sethvflip(struct gspca_dev *gspca_dev);
static void setautobright(struct gspca_dev *gspca_dev); static void setautobright(struct gspca_dev *gspca_dev);
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
static void setfreq(struct gspca_dev *gspca_dev); static void setfreq(struct gspca_dev *gspca_dev);
static void setfreq_i(struct sd *sd); static void setfreq_i(struct sd *sd);
...@@ -173,6 +177,18 @@ static const struct ctrl sd_ctrls[] = { ...@@ -173,6 +177,18 @@ static const struct ctrl sd_ctrls[] = {
}, },
.set_control = setcontrast, .set_control = setcontrast,
}, },
[EXPOSURE] = {
{
.id = V4L2_CID_EXPOSURE,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Exposure",
.minimum = 0,
.maximum = 255,
.step = 1,
.default_value = 127,
},
.set_control = setexposure,
},
[COLORS] = { [COLORS] = {
{ {
.id = V4L2_CID_SATURATION, .id = V4L2_CID_SATURATION,
...@@ -222,6 +238,19 @@ static const struct ctrl sd_ctrls[] = { ...@@ -222,6 +238,19 @@ static const struct ctrl sd_ctrls[] = {
}, },
.set_control = setautobright, .set_control = setautobright,
}, },
[AUTOGAIN] = {
{
.id = V4L2_CID_AUTOGAIN,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "Auto Gain",
.minimum = 0,
.maximum = 1,
.step = 1,
.default_value = 1,
.flags = V4L2_CTRL_FLAG_UPDATE
},
.set = sd_setautogain,
},
[FREQ] = { [FREQ] = {
{ {
.id = V4L2_CID_POWER_LINE_FREQUENCY, .id = V4L2_CID_POWER_LINE_FREQUENCY,
...@@ -238,50 +267,78 @@ static const struct ctrl sd_ctrls[] = { ...@@ -238,50 +267,78 @@ static const struct ctrl sd_ctrls[] = {
/* table of the disabled controls */ /* table of the disabled controls */
static const unsigned ctrl_dis[] = { static const unsigned ctrl_dis[] = {
[SEN_OV2610] = (1 << NCTRL) - 1, /* no control */ [SEN_OV2610] = ((1 << NCTRL) - 1) /* no control */
^ ((1 << EXPOSURE) /* but exposure */
| (1 << AUTOGAIN)), /* and autogain */
[SEN_OV2610AE] = (1 << NCTRL) - 1, /* no control */ [SEN_OV2610AE] = ((1 << NCTRL) - 1) /* no control */
^ ((1 << EXPOSURE) /* but exposure */
| (1 << AUTOGAIN)), /* and autogain */
[SEN_OV3610] = (1 << NCTRL) - 1, /* no control */ [SEN_OV3610] = (1 << NCTRL) - 1, /* no control */
[SEN_OV6620] = (1 << HFLIP) | [SEN_OV6620] = (1 << HFLIP) |
(1 << VFLIP), (1 << VFLIP) |
(1 << EXPOSURE) |
(1 << AUTOGAIN),
[SEN_OV6630] = (1 << HFLIP) | [SEN_OV6630] = (1 << HFLIP) |
(1 << VFLIP), (1 << VFLIP) |
(1 << EXPOSURE) |
(1 << AUTOGAIN),
[SEN_OV66308AF] = (1 << HFLIP) | [SEN_OV66308AF] = (1 << HFLIP) |
(1 << VFLIP), (1 << VFLIP) |
(1 << EXPOSURE) |
(1 << AUTOGAIN),
[SEN_OV7610] = (1 << HFLIP) | [SEN_OV7610] = (1 << HFLIP) |
(1 << VFLIP), (1 << VFLIP) |
(1 << EXPOSURE) |
(1 << AUTOGAIN),
[SEN_OV7620] = (1 << HFLIP) | [SEN_OV7620] = (1 << HFLIP) |
(1 << VFLIP), (1 << VFLIP) |
(1 << EXPOSURE) |
(1 << AUTOGAIN),
[SEN_OV7620AE] = (1 << HFLIP) | [SEN_OV7620AE] = (1 << HFLIP) |
(1 << VFLIP), (1 << VFLIP) |
(1 << EXPOSURE) |
(1 << AUTOGAIN),
[SEN_OV7640] = (1 << HFLIP) | [SEN_OV7640] = (1 << HFLIP) |
(1 << VFLIP) | (1 << VFLIP) |
(1 << AUTOBRIGHT) | (1 << AUTOBRIGHT) |
(1 << CONTRAST), (1 << CONTRAST) |
(1 << EXPOSURE) |
(1 << AUTOGAIN),
[SEN_OV7648] = (1 << HFLIP) | [SEN_OV7648] = (1 << HFLIP) |
(1 << VFLIP) | (1 << VFLIP) |
(1 << AUTOBRIGHT) | (1 << AUTOBRIGHT) |
(1 << CONTRAST), (1 << CONTRAST) |
(1 << EXPOSURE) |
(1 << AUTOGAIN),
[SEN_OV7660] = (1 << AUTOBRIGHT), [SEN_OV7660] = (1 << AUTOBRIGHT) |
(1 << EXPOSURE) |
(1 << AUTOGAIN),
[SEN_OV7670] = (1 << COLORS) | [SEN_OV7670] = (1 << COLORS) |
(1 << AUTOBRIGHT), (1 << AUTOBRIGHT) |
(1 << EXPOSURE) |
(1 << AUTOGAIN),
[SEN_OV76BE] = (1 << HFLIP) | [SEN_OV76BE] = (1 << HFLIP) |
(1 << VFLIP), (1 << VFLIP) |
(1 << EXPOSURE) |
(1 << AUTOGAIN),
[SEN_OV8610] = (1 << HFLIP) | [SEN_OV8610] = (1 << HFLIP) |
(1 << VFLIP) | (1 << VFLIP) |
(1 << EXPOSURE) |
(1 << AUTOGAIN) |
(1 << FREQ), (1 << FREQ),
}; };
...@@ -3201,6 +3258,13 @@ static void ov519_set_fr(struct sd *sd) ...@@ -3201,6 +3258,13 @@ static void ov519_set_fr(struct sd *sd)
ov518_i2c_w(sd, OV7670_R11_CLKRC, clock); ov518_i2c_w(sd, OV7670_R11_CLKRC, clock);
} }
static void setautogain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
i2c_w_mask(sd, 0x13, sd->ctrls[AUTOGAIN].val ? 0x05 : 0x00, 0x05);
}
/* this function is called at probe time */ /* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev, static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id) const struct usb_device_id *id)
...@@ -4189,12 +4253,16 @@ static int sd_start(struct gspca_dev *gspca_dev) ...@@ -4189,12 +4253,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
setcontrast(gspca_dev); setcontrast(gspca_dev);
if (!(sd->gspca_dev.ctrl_dis & (1 << BRIGHTNESS))) if (!(sd->gspca_dev.ctrl_dis & (1 << BRIGHTNESS)))
setbrightness(gspca_dev); setbrightness(gspca_dev);
if (!(sd->gspca_dev.ctrl_dis & (1 << EXPOSURE)))
setexposure(gspca_dev);
if (!(sd->gspca_dev.ctrl_dis & (1 << COLORS))) if (!(sd->gspca_dev.ctrl_dis & (1 << COLORS)))
setcolors(gspca_dev); setcolors(gspca_dev);
if (!(sd->gspca_dev.ctrl_dis & ((1 << HFLIP) | (1 << VFLIP)))) if (!(sd->gspca_dev.ctrl_dis & ((1 << HFLIP) | (1 << VFLIP))))
sethvflip(gspca_dev); sethvflip(gspca_dev);
if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOBRIGHT))) if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOBRIGHT)))
setautobright(gspca_dev); setautobright(gspca_dev);
if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOGAIN)))
setautogain(gspca_dev);
if (!(sd->gspca_dev.ctrl_dis & (1 << FREQ))) if (!(sd->gspca_dev.ctrl_dis & (1 << FREQ)))
setfreq_i(sd); setfreq_i(sd);
...@@ -4608,6 +4676,14 @@ static void setcontrast(struct gspca_dev *gspca_dev) ...@@ -4608,6 +4676,14 @@ static void setcontrast(struct gspca_dev *gspca_dev)
} }
} }
static void setexposure(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
if (!sd->ctrls[AUTOGAIN].val)
i2c_w(sd, 0x10, sd->ctrls[EXPOSURE].val);
}
static void setcolors(struct gspca_dev *gspca_dev) static void setcolors(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
...@@ -4666,6 +4742,22 @@ static void setautobright(struct gspca_dev *gspca_dev) ...@@ -4666,6 +4742,22 @@ static void setautobright(struct gspca_dev *gspca_dev)
i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10); i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10);
} }
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
sd->ctrls[AUTOGAIN].val = val;
if (val) {
gspca_dev->ctrl_inac |= (1 << EXPOSURE);
} else {
gspca_dev->ctrl_inac &= ~(1 << EXPOSURE);
sd->ctrls[EXPOSURE].val = i2c_r(sd, 0x10);
}
if (gspca_dev->streaming)
setautogain(gspca_dev);
return gspca_dev->usb_err;
}
static void setfreq_i(struct sd *sd) static void setfreq_i(struct sd *sd)
{ {
if (sd->sensor == SEN_OV7660 if (sd->sensor == SEN_OV7660
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment