[media] gspca - sonixb: Use the new control mechanism
Acked-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Jean-François Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Родитель
fa85bb6f9b
Коммит
f51a8caafe
|
@ -56,9 +56,22 @@ MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
|
|||
MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/* controls */
|
||||
enum e_ctrl {
|
||||
BRIGHTNESS,
|
||||
GAIN,
|
||||
EXPOSURE,
|
||||
AUTOGAIN,
|
||||
FREQ,
|
||||
NCTRLS /* number of controls */
|
||||
};
|
||||
|
||||
/* specific webcam descriptor */
|
||||
struct sd {
|
||||
struct gspca_dev gspca_dev; /* !! must be the first item */
|
||||
|
||||
struct gspca_ctrl ctrls[NCTRLS];
|
||||
|
||||
atomic_t avg_lum;
|
||||
int prev_avg_lum;
|
||||
int exp_too_low_cnt;
|
||||
|
@ -66,13 +79,8 @@ struct sd {
|
|||
int header_read;
|
||||
u8 header[12]; /* Header without sof marker */
|
||||
|
||||
unsigned short exposure;
|
||||
unsigned char gain;
|
||||
unsigned char brightness;
|
||||
unsigned char autogain;
|
||||
unsigned char autogain_ignore_frames;
|
||||
unsigned char frames_to_drop;
|
||||
unsigned char freq; /* light freq filter setting */
|
||||
|
||||
__u8 bridge; /* Type of bridge */
|
||||
#define BRIDGE_101 0
|
||||
|
@ -113,10 +121,9 @@ struct sensor_data {
|
|||
#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */
|
||||
|
||||
/* ctrl_dis helper macros */
|
||||
#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << COARSE_EXPOSURE_IDX) | \
|
||||
(1 << AUTOGAIN_IDX))
|
||||
#define NO_FREQ (1 << FREQ_IDX)
|
||||
#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
|
||||
#define NO_EXPO ((1 << EXPOSURE) | (1 << AUTOGAIN))
|
||||
#define NO_FREQ (1 << FREQ)
|
||||
#define NO_BRIGHTNESS (1 << BRIGHTNESS)
|
||||
|
||||
#define COMP 0xc7 /* 0x87 //0x07 */
|
||||
#define COMP1 0xc9 /* 0x89 //0x09 */
|
||||
|
@ -141,20 +148,14 @@ struct sensor_data {
|
|||
#define AUTOGAIN_IGNORE_FRAMES 1
|
||||
|
||||
/* V4L2 controls supported by the driver */
|
||||
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
|
||||
static int sd_getbrightness(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 sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
|
||||
static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
|
||||
static void setbrightness(struct gspca_dev *gspca_dev);
|
||||
static void setgain(struct gspca_dev *gspca_dev);
|
||||
static void setexposure(struct gspca_dev *gspca_dev);
|
||||
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
|
||||
static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
|
||||
static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
|
||||
static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
|
||||
static void setfreq(struct gspca_dev *gspca_dev);
|
||||
|
||||
static const struct ctrl sd_ctrls[] = {
|
||||
#define BRIGHTNESS_IDX 0
|
||||
{
|
||||
static const struct ctrl sd_ctrls[NCTRLS] = {
|
||||
[BRIGHTNESS] = {
|
||||
{
|
||||
.id = V4L2_CID_BRIGHTNESS,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
|
@ -162,14 +163,11 @@ static const struct ctrl sd_ctrls[] = {
|
|||
.minimum = 0,
|
||||
.maximum = 255,
|
||||
.step = 1,
|
||||
#define BRIGHTNESS_DEF 127
|
||||
.default_value = BRIGHTNESS_DEF,
|
||||
.default_value = 127,
|
||||
},
|
||||
.set = sd_setbrightness,
|
||||
.get = sd_getbrightness,
|
||||
.set_control = setbrightness
|
||||
},
|
||||
#define GAIN_IDX 1
|
||||
{
|
||||
[GAIN] = {
|
||||
{
|
||||
.id = V4L2_CID_GAIN,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
|
@ -177,48 +175,31 @@ static const struct ctrl sd_ctrls[] = {
|
|||
.minimum = 0,
|
||||
.maximum = 255,
|
||||
.step = 1,
|
||||
#define GAIN_DEF 127
|
||||
#define GAIN_KNEE 230
|
||||
.default_value = GAIN_DEF,
|
||||
.default_value = 127,
|
||||
},
|
||||
.set = sd_setgain,
|
||||
.get = sd_getgain,
|
||||
.set_control = setgain
|
||||
},
|
||||
#define EXPOSURE_IDX 2
|
||||
{
|
||||
[EXPOSURE] = {
|
||||
{
|
||||
.id = V4L2_CID_EXPOSURE,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.name = "Exposure",
|
||||
#define EXPOSURE_DEF 66 /* 33 ms / 30 fps (except on PASXXX) */
|
||||
#define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */
|
||||
.minimum = 0,
|
||||
.maximum = 1023,
|
||||
.step = 1,
|
||||
.default_value = EXPOSURE_DEF,
|
||||
.default_value = 66,
|
||||
/* 33 ms / 30 fps (except on PASXXX) */
|
||||
#define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */
|
||||
.flags = 0,
|
||||
},
|
||||
.set = sd_setexposure,
|
||||
.get = sd_getexposure,
|
||||
.set_control = setexposure
|
||||
},
|
||||
#define COARSE_EXPOSURE_IDX 3
|
||||
{
|
||||
{
|
||||
.id = V4L2_CID_EXPOSURE,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.name = "Exposure",
|
||||
/* for coarse exposure */
|
||||
#define COARSE_EXPOSURE_MIN 2
|
||||
#define COARSE_EXPOSURE_MAX 15
|
||||
#define COARSE_EXPOSURE_DEF 2 /* 30 fps */
|
||||
.minimum = 2,
|
||||
.maximum = 15,
|
||||
.step = 1,
|
||||
.default_value = COARSE_EXPOSURE_DEF,
|
||||
.flags = 0,
|
||||
},
|
||||
.set = sd_setexposure,
|
||||
.get = sd_getexposure,
|
||||
},
|
||||
#define AUTOGAIN_IDX 4
|
||||
{
|
||||
[AUTOGAIN] = {
|
||||
{
|
||||
.id = V4L2_CID_AUTOGAIN,
|
||||
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
||||
|
@ -231,10 +212,8 @@ static const struct ctrl sd_ctrls[] = {
|
|||
.flags = 0,
|
||||
},
|
||||
.set = sd_setautogain,
|
||||
.get = sd_getautogain,
|
||||
},
|
||||
#define FREQ_IDX 5
|
||||
{
|
||||
[FREQ] = {
|
||||
{
|
||||
.id = V4L2_CID_POWER_LINE_FREQUENCY,
|
||||
.type = V4L2_CTRL_TYPE_MENU,
|
||||
|
@ -245,8 +224,7 @@ static const struct ctrl sd_ctrls[] = {
|
|||
#define FREQ_DEF 0
|
||||
.default_value = FREQ_DEF,
|
||||
},
|
||||
.set = sd_setfreq,
|
||||
.get = sd_getfreq,
|
||||
.set_control = setfreq
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -646,7 +624,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
|
|||
|
||||
/* change reg 0x06 */
|
||||
i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
|
||||
i2cOV[3] = sd->brightness;
|
||||
i2cOV[3] = sd->ctrls[BRIGHTNESS].val;
|
||||
if (i2c_w(gspca_dev, i2cOV) < 0)
|
||||
goto err;
|
||||
break;
|
||||
|
@ -664,13 +642,13 @@ static void setbrightness(struct gspca_dev *gspca_dev)
|
|||
i2cpdoit[2] = 0x13;
|
||||
}
|
||||
|
||||
if (sd->brightness < 127) {
|
||||
if (sd->ctrls[BRIGHTNESS].val < 127) {
|
||||
/* change reg 0x0b, signreg */
|
||||
i2cpbright[3] = 0x01;
|
||||
/* set reg 0x0c, offset */
|
||||
i2cpbright[4] = 127 - sd->brightness;
|
||||
i2cpbright[4] = 127 - sd->ctrls[BRIGHTNESS].val;
|
||||
} else
|
||||
i2cpbright[4] = sd->brightness - 127;
|
||||
i2cpbright[4] = sd->ctrls[BRIGHTNESS].val - 127;
|
||||
|
||||
if (i2c_w(gspca_dev, i2cpbright) < 0)
|
||||
goto err;
|
||||
|
@ -687,16 +665,16 @@ err:
|
|||
static void setsensorgain(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
unsigned char gain = sd->gain;
|
||||
u8 gain = sd->ctrls[GAIN].val;
|
||||
|
||||
switch (sd->sensor) {
|
||||
case SENSOR_HV7131D: {
|
||||
__u8 i2c[] =
|
||||
{0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17};
|
||||
|
||||
i2c[3] = 0x3f - (sd->gain / 4);
|
||||
i2c[4] = 0x3f - (sd->gain / 4);
|
||||
i2c[5] = 0x3f - (sd->gain / 4);
|
||||
i2c[3] = 0x3f - (gain / 4);
|
||||
i2c[4] = 0x3f - (gain / 4);
|
||||
i2c[5] = 0x3f - (gain / 4);
|
||||
|
||||
if (i2c_w(gspca_dev, i2c) < 0)
|
||||
goto err;
|
||||
|
@ -759,11 +737,11 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
|
|||
i2cpdoit[2] = 0x13;
|
||||
}
|
||||
|
||||
i2cpgain[3] = sd->gain >> 3;
|
||||
i2cpcolorgain[3] = sd->gain >> 4;
|
||||
i2cpcolorgain[4] = sd->gain >> 4;
|
||||
i2cpcolorgain[5] = sd->gain >> 4;
|
||||
i2cpcolorgain[6] = sd->gain >> 4;
|
||||
i2cpgain[3] = gain >> 3;
|
||||
i2cpcolorgain[3] = gain >> 4;
|
||||
i2cpcolorgain[4] = gain >> 4;
|
||||
i2cpcolorgain[5] = gain >> 4;
|
||||
i2cpcolorgain[6] = gain >> 4;
|
||||
|
||||
if (i2c_w(gspca_dev, i2cpgain) < 0)
|
||||
goto err;
|
||||
|
@ -792,13 +770,13 @@ static void setgain(struct gspca_dev *gspca_dev)
|
|||
}
|
||||
|
||||
if (sd->bridge == BRIDGE_103) {
|
||||
gain = sd->gain >> 1;
|
||||
gain = sd->ctrls[GAIN].val >> 1;
|
||||
buf[0] = gain; /* Red */
|
||||
buf[1] = gain; /* Green */
|
||||
buf[2] = gain; /* Blue */
|
||||
reg_w(gspca_dev, 0x05, buf, 3);
|
||||
} else {
|
||||
gain = sd->gain >> 4;
|
||||
gain = sd->ctrls[GAIN].val >> 4;
|
||||
buf[0] = gain << 4 | gain; /* Red and blue */
|
||||
buf[1] = gain; /* Green */
|
||||
reg_w(gspca_dev, 0x10, buf, 2);
|
||||
|
@ -820,7 +798,8 @@ static void setexposure(struct gspca_dev *gspca_dev)
|
|||
where the framerate starts dropping
|
||||
2) At 6138 the framerate has already dropped to 2 fps,
|
||||
going any lower makes little sense */
|
||||
__u16 reg = sd->exposure * 6;
|
||||
u16 reg = sd->ctrls[EXPOSURE].val * 6;
|
||||
|
||||
i2c[3] = reg >> 8;
|
||||
i2c[4] = reg & 0xff;
|
||||
if (i2c_w(gspca_dev, i2c) != 0)
|
||||
|
@ -832,7 +811,8 @@ static void setexposure(struct gspca_dev *gspca_dev)
|
|||
/* register 19's high nibble contains the sn9c10x clock divider
|
||||
The high nibble configures the no fps according to the
|
||||
formula: 60 / high_nibble. With a maximum of 30 fps */
|
||||
__u8 reg = sd->exposure;
|
||||
u8 reg = sd->ctrls[EXPOSURE].val;
|
||||
|
||||
reg = (reg << 4) | 0x0b;
|
||||
reg_w(gspca_dev, 0x19, ®, 1);
|
||||
break;
|
||||
|
@ -868,7 +848,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
|
|||
} else
|
||||
reg10_max = 0x41;
|
||||
|
||||
reg11 = (15 * sd->exposure + 999) / 1000;
|
||||
reg11 = (15 * sd->ctrls[EXPOSURE].val + 999) / 1000;
|
||||
if (reg11 < 1)
|
||||
reg11 = 1;
|
||||
else if (reg11 > 16)
|
||||
|
@ -881,14 +861,16 @@ static void setexposure(struct gspca_dev *gspca_dev)
|
|||
reg11 = 4;
|
||||
|
||||
/* frame exposure time in ms = 1000 * reg11 / 30 ->
|
||||
reg10 = (sd->exposure / 2) * reg10_max / (1000 * reg11 / 30) */
|
||||
reg10 = (sd->exposure * 15 * reg10_max) / (1000 * reg11);
|
||||
reg10 = (sd->ctrls[EXPOSURE].val / 2) * reg10_max
|
||||
/ (1000 * reg11 / 30) */
|
||||
reg10 = (sd->ctrls[EXPOSURE].val * 15 * reg10_max)
|
||||
/ (1000 * reg11);
|
||||
|
||||
/* Don't allow this to get below 10 when using autogain, the
|
||||
steps become very large (relatively) when below 10 causing
|
||||
the image to oscilate from much too dark, to much too bright
|
||||
and back again. */
|
||||
if (sd->autogain && reg10 < 10)
|
||||
if (sd->ctrls[AUTOGAIN].val && reg10 < 10)
|
||||
reg10 = 10;
|
||||
else if (reg10 > reg10_max)
|
||||
reg10 = reg10_max;
|
||||
|
@ -927,15 +909,16 @@ static void setexposure(struct gspca_dev *gspca_dev)
|
|||
frame exposure times (like we are doing with the ov chips),
|
||||
as that sometimes leads to jumps in the exposure control,
|
||||
which are bad for auto exposure. */
|
||||
if (sd->exposure < 200) {
|
||||
i2cpexpo[3] = 255 - (sd->exposure * 255) / 200;
|
||||
if (sd->ctrls[EXPOSURE].val < 200) {
|
||||
i2cpexpo[3] = 255 - (sd->ctrls[EXPOSURE].val * 255)
|
||||
/ 200;
|
||||
framerate_ctrl = 500;
|
||||
} else {
|
||||
/* The PAS202's exposure control goes from 0 - 4095,
|
||||
but anything below 500 causes vsync issues, so scale
|
||||
our 200-1023 to 500-4095 */
|
||||
framerate_ctrl = (sd->exposure - 200) * 1000 / 229 +
|
||||
500;
|
||||
framerate_ctrl = (sd->ctrls[EXPOSURE].val - 200)
|
||||
* 1000 / 229 + 500;
|
||||
}
|
||||
|
||||
i2cpframerate[3] = framerate_ctrl >> 6;
|
||||
|
@ -959,15 +942,15 @@ static void setexposure(struct gspca_dev *gspca_dev)
|
|||
|
||||
/* For values below 150 use partial frame exposure, above
|
||||
that use framerate ctrl */
|
||||
if (sd->exposure < 150) {
|
||||
i2cpexpo[3] = 150 - sd->exposure;
|
||||
if (sd->ctrls[EXPOSURE].val < 150) {
|
||||
i2cpexpo[3] = 150 - sd->ctrls[EXPOSURE].val;
|
||||
framerate_ctrl = 300;
|
||||
} else {
|
||||
/* The PAS106's exposure control goes from 0 - 4095,
|
||||
but anything below 300 causes vsync issues, so scale
|
||||
our 150-1023 to 300-4095 */
|
||||
framerate_ctrl = (sd->exposure - 150) * 1000 / 230 +
|
||||
300;
|
||||
framerate_ctrl = (sd->ctrls[EXPOSURE].val - 150)
|
||||
* 1000 / 230 + 300;
|
||||
}
|
||||
|
||||
i2cpframerate[3] = framerate_ctrl >> 4;
|
||||
|
@ -998,7 +981,7 @@ static void setfreq(struct gspca_dev *gspca_dev)
|
|||
0x2b register, see ov6630 datasheet.
|
||||
0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
|
||||
__u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
|
||||
switch (sd->freq) {
|
||||
switch (sd->ctrls[FREQ].val) {
|
||||
default:
|
||||
/* case 0: * no filter*/
|
||||
/* case 2: * 60 hz */
|
||||
|
@ -1017,7 +1000,7 @@ static void setfreq(struct gspca_dev *gspca_dev)
|
|||
}
|
||||
}
|
||||
|
||||
#include "coarse_expo_autogain.h"
|
||||
#include "autogain_functions.h"
|
||||
|
||||
static void do_autogain(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
|
@ -1025,7 +1008,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
|
|||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int avg_lum = atomic_read(&sd->avg_lum);
|
||||
|
||||
if (avg_lum == -1 || !sd->autogain)
|
||||
if (avg_lum == -1 || !sd->ctrls[AUTOGAIN].val)
|
||||
return;
|
||||
|
||||
if (sd->autogain_ignore_frames > 0) {
|
||||
|
@ -1045,17 +1028,20 @@ static void do_autogain(struct gspca_dev *gspca_dev)
|
|||
}
|
||||
|
||||
if (sensor_data[sd->sensor].flags & F_COARSE_EXPO)
|
||||
result = gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
|
||||
sd->brightness * desired_avg_lum / 127,
|
||||
result = coarse_grained_expo_autogain(gspca_dev, avg_lum,
|
||||
sd->ctrls[BRIGHTNESS].val
|
||||
* desired_avg_lum / 127,
|
||||
deadzone);
|
||||
else
|
||||
result = gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
|
||||
sd->brightness * desired_avg_lum / 127,
|
||||
result = auto_gain_n_exposure(gspca_dev, avg_lum,
|
||||
sd->ctrls[BRIGHTNESS].val
|
||||
* desired_avg_lum / 127,
|
||||
deadzone, GAIN_KNEE, EXPOSURE_KNEE);
|
||||
|
||||
if (result) {
|
||||
PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d",
|
||||
(int)sd->gain, (int)sd->exposure);
|
||||
(int) sd->ctrls[GAIN].val,
|
||||
(int) sd->ctrls[EXPOSURE].val);
|
||||
sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
|
||||
}
|
||||
}
|
||||
|
@ -1074,9 +1060,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
|||
/* copy the webcam info from the device id */
|
||||
sd->sensor = id->driver_info >> 8;
|
||||
sd->bridge = id->driver_info & 0xff;
|
||||
|
||||
gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
|
||||
|
||||
cam = &gspca_dev->cam;
|
||||
cam->ctrls = sd->ctrls;
|
||||
if (!(sensor_data[sd->sensor].flags & F_SIF)) {
|
||||
cam->cam_mode = vga_mode;
|
||||
cam->nmodes = ARRAY_SIZE(vga_mode);
|
||||
|
@ -1086,20 +1074,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
|||
}
|
||||
cam->npkt = 36; /* 36 packets per ISOC message */
|
||||
|
||||
sd->brightness = BRIGHTNESS_DEF;
|
||||
sd->gain = GAIN_DEF;
|
||||
if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) {
|
||||
sd->exposure = COARSE_EXPOSURE_DEF;
|
||||
gspca_dev->ctrl_dis |= (1 << EXPOSURE_IDX);
|
||||
} else {
|
||||
sd->exposure = EXPOSURE_DEF;
|
||||
gspca_dev->ctrl_dis |= (1 << COARSE_EXPOSURE_IDX);
|
||||
sd->ctrls[EXPOSURE].min = COARSE_EXPOSURE_MIN;
|
||||
sd->ctrls[EXPOSURE].max = COARSE_EXPOSURE_MAX;
|
||||
sd->ctrls[EXPOSURE].def = COARSE_EXPOSURE_DEF;
|
||||
}
|
||||
if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
|
||||
sd->autogain = 0; /* Disable do_autogain callback */
|
||||
else
|
||||
sd->autogain = AUTOGAIN_DEF;
|
||||
sd->freq = FREQ_DEF;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1398,65 +1377,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
|||
}
|
||||
}
|
||||
|
||||
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
sd->brightness = val;
|
||||
if (gspca_dev->streaming)
|
||||
setbrightness(gspca_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
*val = sd->brightness;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int 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);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
*val = sd->gain;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
sd->exposure = val;
|
||||
if (gspca_dev->streaming)
|
||||
setexposure(gspca_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
*val = sd->exposure;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
sd->autogain = val;
|
||||
sd->ctrls[AUTOGAIN].val = val;
|
||||
sd->exp_too_high_cnt = 0;
|
||||
sd->exp_too_low_cnt = 0;
|
||||
|
||||
|
@ -1464,9 +1389,10 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
|
|||
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 && !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) {
|
||||
sd->exposure = EXPOSURE_DEF;
|
||||
sd->gain = GAIN_DEF;
|
||||
if (sd->ctrls[AUTOGAIN].val
|
||||
&& !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) {
|
||||
sd->ctrls[EXPOSURE].val = sd->ctrls[EXPOSURE].def;
|
||||
sd->ctrls[GAIN].val = sd->ctrls[GAIN].def;
|
||||
if (gspca_dev->streaming) {
|
||||
sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
|
||||
setexposure(gspca_dev);
|
||||
|
@ -1477,32 +1403,6 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
*val = sd->autogain;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
sd->freq = val;
|
||||
if (gspca_dev->streaming)
|
||||
setfreq(gspca_dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
*val = sd->freq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_querymenu(struct gspca_dev *gspca_dev,
|
||||
struct v4l2_querymenu *menu)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче