@@ -89,8 +89,10 @@ static int pac7302_sd_getcontrast(struct
static int pac7311_sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
static int pac7302_sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
static int pac7302_sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
+static int pac7302_sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
+static int pac7311_sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
+static int pac7302_sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
+static int pac7311_sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
static int pac7302_sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
static int pac7311_sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
static int pac7302_sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
@@ -99,8 +101,10 @@ static int pac7302_sd_setvflip(struct gs
static int pac7311_sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
static int pac7302_sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
static int pac7311_sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
+static int pac7302_sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
+static int pac7311_sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
+static int pac7302_sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
+static int pac7311_sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
@@ -167,8 +171,8 @@ static struct ctrl pac7302_sd_ctrls[] =
#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
.default_value = GAIN_DEF,
},
- .set = sd_setgain,
- .get = sd_getgain,
+ .set = pac7302_sd_setgain,
+ .get = pac7302_sd_getgain,
},
{
{
@@ -197,8 +201,8 @@ static struct ctrl pac7302_sd_ctrls[] =
#define AUTOGAIN_DEF 1
.default_value = AUTOGAIN_DEF,
},
- .set = sd_setautogain,
- .get = sd_getautogain,
+ .set = pac7302_sd_setautogain,
+ .get = pac7302_sd_getautogain,
},
{
{
@@ -261,8 +265,8 @@ static struct ctrl pac7311_sd_ctrls[] =
#define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
.default_value = GAIN_DEF,
},
- .set = sd_setgain,
- .get = sd_getgain,
+ .set = pac7311_sd_setgain,
+ .get = pac7311_sd_getgain,
},
{
{
@@ -291,8 +295,8 @@ static struct ctrl pac7311_sd_ctrls[] =
#define AUTOGAIN_DEF 1
.default_value = AUTOGAIN_DEF,
},
- .set = sd_setautogain,
- .get = sd_getautogain,
+ .set = pac7311_sd_setautogain,
+ .get = pac7311_sd_getautogain,
},
{
{
@@ -717,23 +721,30 @@ static void pac7302_setcolors(struct gsp
PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
}
-static void setgain(struct gspca_dev *gspca_dev)
+static void pac7302_setgain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- if (sd->sensor == SENSOR_PAC7302) {
- reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
- reg_w(gspca_dev, 0x10, sd->gain >> 3);
- } else {
- int gain = GAIN_MAX - sd->gain;
- if (gain < 1)
- gain = 1;
- else if (gain > 245)
- gain = 245;
- reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
- reg_w(gspca_dev, 0x0e, 0x00);
- reg_w(gspca_dev, 0x0f, gain);
- }
+ reg_w(gspca_dev, 0xff, 0x03); /* page 3 */
+ reg_w(gspca_dev, 0x10, sd->gain >> 3);
+
+ /* load registers to sensor (Bit 0, auto clear) */
+ reg_w(gspca_dev, 0x11, 0x01);
+}
+
+static void pac7311_setgain(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int gain = GAIN_MAX - sd->gain;
+
+ if (gain < 1)
+ gain = 1;
+ else if (gain > 245)
+ gain = 245;
+ reg_w(gspca_dev, 0xff, 0x04); /* page 4 */
+ reg_w(gspca_dev, 0x0e, 0x00);
+ reg_w(gspca_dev, 0x0f, gain);
+
/* load registers to sensor (Bit 0, auto clear) */
reg_w(gspca_dev, 0x11, 0x01);
}
@@ -824,7 +835,7 @@ static int pac7302_sd_start(struct gspca
reg_w_var(gspca_dev, start_7302);
pac7302_setbrightcont(gspca_dev);
pac7302_setcolors(gspca_dev);
- setgain(gspca_dev);
+ pac7302_setgain(gspca_dev);
setexposure(gspca_dev);
pac7302_sethvflip(gspca_dev);
@@ -849,7 +860,7 @@ static int pac7311_sd_start(struct gspca
reg_w_var(gspca_dev, start_7311);
pac7311_setcontrast(gspca_dev);
- setgain(gspca_dev);
+ pac7311_setgain(gspca_dev);
setexposure(gspca_dev);
pac7311_sethvflip(gspca_dev);
@@ -1197,17 +1208,35 @@ static int pac7302_sd_getcolors(struct g
return 0;
}
-static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
+static int pac7302_sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
sd->gain = val;
if (gspca_dev->streaming)
- setgain(gspca_dev);
+ pac7302_setgain(gspca_dev);
return 0;
}
-static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
+static int pac7311_sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->gain = val;
+ if (gspca_dev->streaming)
+ pac7311_setgain(gspca_dev);
+ return 0;
+}
+
+static int pac7302_sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->gain;
+ return 0;
+}
+
+static int pac7311_sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1233,7 +1262,7 @@ static int sd_getexposure(struct gspca_d
return 0;
}
-static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
+static int pac7302_sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1249,14 +1278,45 @@ static int sd_setautogain(struct gspca_d
sd->autogain_ignore_frames =
PAC_AUTOGAIN_IGNORE_FRAMES;
setexposure(gspca_dev);
- setgain(gspca_dev);
+ pac7302_setgain(gspca_dev);
}
}
return 0;
}
-static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
+static int pac7311_sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->autogain = val;
+ /* when switching to autogain set defaults to make sure
+ we are on a valid point of the autogain gain /
+ exposure knee graph, and give this change time to
+ take effect before doing autogain. */
+ if (sd->autogain) {
+ sd->exposure = EXPOSURE_DEF;
+ sd->gain = GAIN_DEF;
+ if (gspca_dev->streaming) {
+ sd->autogain_ignore_frames =
+ PAC_AUTOGAIN_IGNORE_FRAMES;
+ setexposure(gspca_dev);
+ pac7311_setgain(gspca_dev);
+ }
+ }
+
+ return 0;
+}
+
+static int pac7302_sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->autogain;
+ return 0;
+}
+
+static int pac7311_sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;