V4L/DVB (11871): gspca - spca561: Change the Rev12a controls.

- Extend the gain range
- Adjust the exposure
- Remove the broken autogain

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Hans de Goede 2009-05-25 15:20:16 -03:00 committed by Mauro Carvalho Chehab
parent 191d0e7fba
commit d0848eb286

View file

@ -34,8 +34,8 @@ struct sd {
__u16 exposure; /* rev12a only */
#define EXPOSURE_MIN 1
#define EXPOSURE_DEF 200
#define EXPOSURE_MAX (4095 - 900) /* see set_exposure */
#define EXPOSURE_DEF 700 /* == 10 fps */
#define EXPOSURE_MAX (2047 + 325) /* see setexposure */
__u8 contrast; /* rev72a only */
#define CONTRAST_MIN 0x00
@ -58,9 +58,9 @@ struct sd {
#define AUTOGAIN_MAX 1
__u8 gain; /* rev12a only */
#define GAIN_MIN 0x0
#define GAIN_DEF 0x24
#define GAIN_MAX 0x24
#define GAIN_MIN 0
#define GAIN_DEF 63
#define GAIN_MAX 255
#define EXPO12A_DEF 3
__u8 expo12a; /* expo/gain? for rev 12a */
@ -549,8 +549,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
static void setexposure(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int expo;
int clock_divider;
int i, expo = 0;
/* Register 0x8309 controls exposure for the spca561,
the basic exposure setting goes from 1-2047, where 1 is completely
@ -564,16 +563,22 @@ static void setexposure(struct gspca_dev *gspca_dev)
configure a divider for the base framerate which us used at the
exposure setting of 1-300. These bits configure the base framerate
according to the following formula: fps = 60 / (value + 2) */
if (sd->exposure < 2048) {
expo = sd->exposure;
clock_divider = 0;
} else {
/* Add 900 to make the 0 setting of the second part of the
exposure equal to the 2047 setting of the first part. */
expo = (sd->exposure - 2048) + 900;
clock_divider = 3;
/* We choose to use the high bits setting the fixed framerate divisor
asap, as setting high basic exposure setting without the fixed
divider in combination with high gains makes the cam stop */
int table[] = { 0, 450, 550, 625, EXPOSURE_MAX };
for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
if (sd->exposure <= table[i + 1]) {
expo = sd->exposure - table[i];
if (i)
expo += 300;
expo |= i << 11;
break;
}
}
expo |= clock_divider << 11;
gspca_dev->usb_buf[0] = expo;
gspca_dev->usb_buf[1] = expo >> 8;
reg_w_buf(gspca_dev, 0x8309, 2);
@ -584,7 +589,16 @@ static void setgain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
gspca_dev->usb_buf[0] = sd->gain;
/* gain reg low 6 bits 0-63 gain, bit 6 and 7, both double the
sensitivity when set, so 31 + one of them set == 63, and 15
with both of them set == 63 */
if (sd->gain < 64)
gspca_dev->usb_buf[0] = sd->gain;
else if (sd->gain < 128)
gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40;
else
gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xC0;
gspca_dev->usb_buf[1] = 0;
reg_w_buf(gspca_dev, 0x8335, 2);
}
@ -629,8 +643,7 @@ static int sd_start_12a(struct gspca_dev *gspca_dev)
reg_w_buf(gspca_dev, 0x8391, 8);
reg_w_buf(gspca_dev, 0x8390, 8);
setwhite(gspca_dev);
setautogain(gspca_dev);
/* setgain(gspca_dev); */
setgain(gspca_dev);
setexposure(gspca_dev);
return 0;
}
@ -762,18 +775,6 @@ static void do_autogain(struct gspca_dev *gspca_dev)
i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
}
break;
case Rev012A:
reg_r(gspca_dev, 0x8330, 2);
if (gspca_dev->usb_buf[1] > 0x08) {
gspca_dev->usb_buf[0] = ++sd->expo12a;
gspca_dev->usb_buf[1] = 0;
reg_w_buf(gspca_dev, 0x8339, 2);
} else if (gspca_dev->usb_buf[1] < 0x02) {
gspca_dev->usb_buf[0] = --sd->expo12a;
gspca_dev->usb_buf[1] = 0;
reg_w_buf(gspca_dev, 0x8339, 2);
}
break;
}
}
@ -952,19 +953,6 @@ static struct ctrl sd_ctrls_12a[] = {
.set = sd_setexposure,
.get = sd_getexposure,
},
{
{
.id = V4L2_CID_AUTOGAIN,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "Auto Gain",
.minimum = AUTOGAIN_MIN,
.maximum = AUTOGAIN_MAX,
.step = 1,
.default_value = AUTOGAIN_DEF,
},
.set = sd_setautogain,
.get = sd_getautogain,
},
{
{
.id = V4L2_CID_GAIN,
@ -1046,7 +1034,6 @@ static const struct sd_desc sd_desc_12a = {
.stopN = sd_stopN,
.stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
/* .dq_callback = do_autogain, * fixme */
};
static const struct sd_desc sd_desc_72a = {
.name = MODULE_NAME,