mirror of
https://github.com/torvalds/linux.git
synced 2024-11-08 13:11:45 +00:00
[media] gspca_zc3xx: Convert to the control framework
The initial version was done by HV, corrections were made by HdG, and some final small changes again by HV. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
1b3bbcf5ab
commit
c06ba2804a
@ -35,26 +35,23 @@ static int force_sensor = -1;
|
||||
#define REG08_DEF 3 /* default JPEG compression (75%) */
|
||||
#include "zc3xx-reg.h"
|
||||
|
||||
/* controls */
|
||||
enum e_ctrl {
|
||||
BRIGHTNESS,
|
||||
CONTRAST,
|
||||
EXPOSURE,
|
||||
GAMMA,
|
||||
AUTOGAIN,
|
||||
LIGHTFREQ,
|
||||
SHARPNESS,
|
||||
QUALITY,
|
||||
NCTRLS /* number of controls */
|
||||
};
|
||||
|
||||
#define AUTOGAIN_DEF 1
|
||||
|
||||
/* specific webcam descriptor */
|
||||
struct sd {
|
||||
struct gspca_dev gspca_dev; /* !! must be the first item */
|
||||
|
||||
struct gspca_ctrl ctrls[NCTRLS];
|
||||
struct v4l2_ctrl_handler ctrl_handler;
|
||||
struct { /* gamma/brightness/contrast control cluster */
|
||||
struct v4l2_ctrl *gamma;
|
||||
struct v4l2_ctrl *brightness;
|
||||
struct v4l2_ctrl *contrast;
|
||||
};
|
||||
struct { /* autogain/exposure control cluster */
|
||||
struct v4l2_ctrl *autogain;
|
||||
struct v4l2_ctrl *exposure;
|
||||
};
|
||||
struct v4l2_ctrl *plfreq;
|
||||
struct v4l2_ctrl *sharpness;
|
||||
struct v4l2_ctrl *jpegqual;
|
||||
|
||||
struct work_struct work;
|
||||
struct workqueue_struct *work_thread;
|
||||
@ -94,114 +91,6 @@ enum sensors {
|
||||
SENSOR_MAX
|
||||
};
|
||||
|
||||
/* V4L2 controls supported by the driver */
|
||||
static void setcontrast(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 void setlightfreq(struct gspca_dev *gspca_dev);
|
||||
static void setsharpness(struct gspca_dev *gspca_dev);
|
||||
static int sd_setquality(struct gspca_dev *gspca_dev, __s32 val);
|
||||
|
||||
static const struct ctrl sd_ctrls[NCTRLS] = {
|
||||
[BRIGHTNESS] = {
|
||||
{
|
||||
.id = V4L2_CID_BRIGHTNESS,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.name = "Brightness",
|
||||
.minimum = 0,
|
||||
.maximum = 255,
|
||||
.step = 1,
|
||||
.default_value = 128,
|
||||
},
|
||||
.set_control = setcontrast
|
||||
},
|
||||
[CONTRAST] = {
|
||||
{
|
||||
.id = V4L2_CID_CONTRAST,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.name = "Contrast",
|
||||
.minimum = 0,
|
||||
.maximum = 255,
|
||||
.step = 1,
|
||||
.default_value = 128,
|
||||
},
|
||||
.set_control = setcontrast
|
||||
},
|
||||
[EXPOSURE] = {
|
||||
{
|
||||
.id = V4L2_CID_EXPOSURE,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.name = "Exposure",
|
||||
.minimum = 0x30d,
|
||||
.maximum = 0x493e,
|
||||
.step = 1,
|
||||
.default_value = 0x927
|
||||
},
|
||||
.set_control = setexposure
|
||||
},
|
||||
[GAMMA] = {
|
||||
{
|
||||
.id = V4L2_CID_GAMMA,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.name = "Gamma",
|
||||
.minimum = 1,
|
||||
.maximum = 6,
|
||||
.step = 1,
|
||||
.default_value = 4,
|
||||
},
|
||||
.set_control = setcontrast
|
||||
},
|
||||
[AUTOGAIN] = {
|
||||
{
|
||||
.id = V4L2_CID_AUTOGAIN,
|
||||
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
||||
.name = "Auto Gain",
|
||||
.minimum = 0,
|
||||
.maximum = 1,
|
||||
.step = 1,
|
||||
.default_value = AUTOGAIN_DEF,
|
||||
.flags = V4L2_CTRL_FLAG_UPDATE
|
||||
},
|
||||
.set = sd_setautogain
|
||||
},
|
||||
[LIGHTFREQ] = {
|
||||
{
|
||||
.id = V4L2_CID_POWER_LINE_FREQUENCY,
|
||||
.type = V4L2_CTRL_TYPE_MENU,
|
||||
.name = "Light frequency filter",
|
||||
.minimum = 0,
|
||||
.maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
|
||||
.step = 1,
|
||||
.default_value = 0,
|
||||
},
|
||||
.set_control = setlightfreq
|
||||
},
|
||||
[SHARPNESS] = {
|
||||
{
|
||||
.id = V4L2_CID_SHARPNESS,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.name = "Sharpness",
|
||||
.minimum = 0,
|
||||
.maximum = 3,
|
||||
.step = 1,
|
||||
.default_value = 2,
|
||||
},
|
||||
.set_control = setsharpness
|
||||
},
|
||||
[QUALITY] = {
|
||||
{
|
||||
.id = V4L2_CID_JPEG_COMPRESSION_QUALITY,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.name = "Compression Quality",
|
||||
.minimum = 50,
|
||||
.maximum = 87,
|
||||
.step = 1,
|
||||
.default_value = 75,
|
||||
},
|
||||
.set = sd_setquality
|
||||
},
|
||||
};
|
||||
|
||||
static const struct v4l2_pix_format vga_mode[] = {
|
||||
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
|
||||
.bytesperline = 320,
|
||||
@ -5821,10 +5710,8 @@ static void setmatrix(struct gspca_dev *gspca_dev)
|
||||
reg_w(gspca_dev, matrix[i], 0x010a + i);
|
||||
}
|
||||
|
||||
static void setsharpness(struct gspca_dev *gspca_dev)
|
||||
static void setsharpness(struct gspca_dev *gspca_dev, s32 val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int sharpness;
|
||||
static const u8 sharpness_tb[][2] = {
|
||||
{0x02, 0x03},
|
||||
{0x04, 0x07},
|
||||
@ -5832,19 +5719,18 @@ static void setsharpness(struct gspca_dev *gspca_dev)
|
||||
{0x10, 0x1e}
|
||||
};
|
||||
|
||||
sharpness = sd->ctrls[SHARPNESS].val;
|
||||
reg_w(gspca_dev, sharpness_tb[sharpness][0], 0x01c6);
|
||||
reg_w(gspca_dev, sharpness_tb[val][0], 0x01c6);
|
||||
reg_r(gspca_dev, 0x01c8);
|
||||
reg_r(gspca_dev, 0x01c9);
|
||||
reg_r(gspca_dev, 0x01ca);
|
||||
reg_w(gspca_dev, sharpness_tb[sharpness][1], 0x01cb);
|
||||
reg_w(gspca_dev, sharpness_tb[val][1], 0x01cb);
|
||||
}
|
||||
|
||||
static void setcontrast(struct gspca_dev *gspca_dev)
|
||||
static void setcontrast(struct gspca_dev *gspca_dev,
|
||||
s32 gamma, s32 brightness, s32 contrast)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
const u8 *Tgamma;
|
||||
int g, i, brightness, contrast, adj, gp1, gp2;
|
||||
int g, i, adj, gp1, gp2;
|
||||
u8 gr[16];
|
||||
static const u8 delta_b[16] = /* delta for brightness */
|
||||
{0x50, 0x38, 0x2d, 0x28, 0x24, 0x21, 0x1e, 0x1d,
|
||||
@ -5867,10 +5753,10 @@ static void setcontrast(struct gspca_dev *gspca_dev)
|
||||
0xe0, 0xeb, 0xf4, 0xff, 0xff, 0xff, 0xff, 0xff},
|
||||
};
|
||||
|
||||
Tgamma = gamma_tb[sd->ctrls[GAMMA].val - 1];
|
||||
Tgamma = gamma_tb[gamma - 1];
|
||||
|
||||
contrast = ((int) sd->ctrls[CONTRAST].val - 128); /* -128 / 127 */
|
||||
brightness = ((int) sd->ctrls[BRIGHTNESS].val - 128); /* -128 / 92 */
|
||||
contrast -= 128; /* -128 / 127 */
|
||||
brightness -= 128; /* -128 / 92 */
|
||||
adj = 0;
|
||||
gp1 = gp2 = 0;
|
||||
for (i = 0; i < 16; i++) {
|
||||
@ -5897,25 +5783,15 @@ static void setcontrast(struct gspca_dev *gspca_dev)
|
||||
reg_w(gspca_dev, gr[i], 0x0130 + i); /* gradient */
|
||||
}
|
||||
|
||||
static void getexposure(struct gspca_dev *gspca_dev)
|
||||
static s32 getexposure(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
if (sd->sensor != SENSOR_HV7131R)
|
||||
return;
|
||||
sd->ctrls[EXPOSURE].val = (i2c_read(gspca_dev, 0x25) << 9)
|
||||
return (i2c_read(gspca_dev, 0x25) << 9)
|
||||
| (i2c_read(gspca_dev, 0x26) << 1)
|
||||
| (i2c_read(gspca_dev, 0x27) >> 7);
|
||||
}
|
||||
|
||||
static void setexposure(struct gspca_dev *gspca_dev)
|
||||
static void setexposure(struct gspca_dev *gspca_dev, s32 val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int val;
|
||||
|
||||
if (sd->sensor != SENSOR_HV7131R)
|
||||
return;
|
||||
val = sd->ctrls[EXPOSURE].val;
|
||||
i2c_write(gspca_dev, 0x25, val >> 9, 0x00);
|
||||
i2c_write(gspca_dev, 0x26, val >> 1, 0x00);
|
||||
i2c_write(gspca_dev, 0x27, val << 7, 0x00);
|
||||
@ -5934,7 +5810,7 @@ static void setquality(struct gspca_dev *gspca_dev)
|
||||
* 60Hz, for American lighting
|
||||
* 0 = No Fliker (for outdoore usage)
|
||||
*/
|
||||
static void setlightfreq(struct gspca_dev *gspca_dev)
|
||||
static void setlightfreq(struct gspca_dev *gspca_dev, s32 val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int i, mode;
|
||||
@ -6018,7 +5894,7 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
|
||||
tas5130c_60HZ, tas5130c_60HZScale},
|
||||
};
|
||||
|
||||
i = sd->ctrls[LIGHTFREQ].val * 2;
|
||||
i = val * 2;
|
||||
mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
|
||||
if (mode)
|
||||
i++; /* 320x240 */
|
||||
@ -6028,14 +5904,14 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
|
||||
usb_exchange(gspca_dev, zc3_freq);
|
||||
switch (sd->sensor) {
|
||||
case SENSOR_GC0305:
|
||||
if (mode /* if 320x240 */
|
||||
&& sd->ctrls[LIGHTFREQ].val == 1) /* and 50Hz */
|
||||
if (mode /* if 320x240 */
|
||||
&& val == 1) /* and 50Hz */
|
||||
reg_w(gspca_dev, 0x85, 0x018d);
|
||||
/* win: 0x80, 0x018d */
|
||||
break;
|
||||
case SENSOR_OV7620:
|
||||
if (!mode) { /* if 640x480 */
|
||||
if (sd->ctrls[LIGHTFREQ].val != 0) /* and filter */
|
||||
if (!mode) { /* if 640x480 */
|
||||
if (val != 0) /* and filter */
|
||||
reg_w(gspca_dev, 0x40, 0x0002);
|
||||
else
|
||||
reg_w(gspca_dev, 0x44, 0x0002);
|
||||
@ -6047,16 +5923,9 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
|
||||
}
|
||||
}
|
||||
|
||||
static void setautogain(struct gspca_dev *gspca_dev)
|
||||
static void setautogain(struct gspca_dev *gspca_dev, s32 val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
u8 autoval;
|
||||
|
||||
if (sd->ctrls[AUTOGAIN].val)
|
||||
autoval = 0x42;
|
||||
else
|
||||
autoval = 0x02;
|
||||
reg_w(gspca_dev, autoval, 0x0180);
|
||||
reg_w(gspca_dev, val ? 0x42 : 0x02, 0x0180);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -6450,7 +6319,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
||||
/* define some sensors from the vendor/product */
|
||||
sd->sensor = id->driver_info;
|
||||
|
||||
gspca_dev->cam.ctrls = sd->ctrls;
|
||||
sd->reg08 = REG08_DEF;
|
||||
|
||||
INIT_WORK(&sd->work, transfer_update);
|
||||
@ -6458,12 +6326,85 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* this function is called at probe and resume time */
|
||||
static int sd_init(struct gspca_dev *gspca_dev)
|
||||
static int zcxx_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
struct cam *cam;
|
||||
int sensor;
|
||||
struct sd *sd = container_of(ctrl->handler, struct sd, ctrl_handler);
|
||||
struct gspca_dev *gspca_dev = &sd->gspca_dev;
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_AUTOGAIN:
|
||||
gspca_dev->usb_err = 0;
|
||||
if (ctrl->val && sd->exposure && gspca_dev->streaming)
|
||||
sd->exposure->val = getexposure(gspca_dev);
|
||||
return gspca_dev->usb_err;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int zcxx_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct sd *sd = container_of(ctrl->handler, struct sd, ctrl_handler);
|
||||
struct gspca_dev *gspca_dev = &sd->gspca_dev;
|
||||
int i, qual;
|
||||
|
||||
gspca_dev->usb_err = 0;
|
||||
|
||||
if (ctrl->id == V4L2_CID_JPEG_COMPRESSION_QUALITY) {
|
||||
qual = sd->reg08 >> 1;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(jpeg_qual); i++) {
|
||||
if (ctrl->val <= jpeg_qual[i])
|
||||
break;
|
||||
}
|
||||
if (i > 0 && i == qual && ctrl->val < jpeg_qual[i])
|
||||
i--;
|
||||
|
||||
/* With high quality settings we need max bandwidth */
|
||||
if (i >= 2 && gspca_dev->streaming &&
|
||||
!gspca_dev->cam.needs_full_bandwidth)
|
||||
return -EBUSY;
|
||||
|
||||
sd->reg08 = (i << 1) | 1;
|
||||
ctrl->val = jpeg_qual[i];
|
||||
}
|
||||
|
||||
if (!gspca_dev->streaming)
|
||||
return 0;
|
||||
|
||||
switch (ctrl->id) {
|
||||
/* gamma/brightness/contrast cluster */
|
||||
case V4L2_CID_GAMMA:
|
||||
setcontrast(gspca_dev, sd->gamma->val,
|
||||
sd->brightness->val, sd->contrast->val);
|
||||
break;
|
||||
/* autogain/exposure cluster */
|
||||
case V4L2_CID_AUTOGAIN:
|
||||
setautogain(gspca_dev, ctrl->val);
|
||||
if (!gspca_dev->usb_err && !ctrl->val && sd->exposure)
|
||||
setexposure(gspca_dev, sd->exposure->val);
|
||||
break;
|
||||
case V4L2_CID_POWER_LINE_FREQUENCY:
|
||||
setlightfreq(gspca_dev, ctrl->val);
|
||||
break;
|
||||
case V4L2_CID_SHARPNESS:
|
||||
setsharpness(gspca_dev, ctrl->val);
|
||||
break;
|
||||
case V4L2_CID_JPEG_COMPRESSION_QUALITY:
|
||||
setquality(gspca_dev);
|
||||
break;
|
||||
}
|
||||
return gspca_dev->usb_err;
|
||||
}
|
||||
|
||||
static const struct v4l2_ctrl_ops zcxx_ctrl_ops = {
|
||||
.g_volatile_ctrl = zcxx_g_volatile_ctrl,
|
||||
.s_ctrl = zcxx_s_ctrl,
|
||||
};
|
||||
|
||||
static int sd_init_controls(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *)gspca_dev;
|
||||
struct v4l2_ctrl_handler *hdl = &sd->ctrl_handler;
|
||||
static const u8 gamma[SENSOR_MAX] = {
|
||||
[SENSOR_ADCM2700] = 4,
|
||||
[SENSOR_CS2102] = 4,
|
||||
@ -6485,6 +6426,48 @@ static int sd_init(struct gspca_dev *gspca_dev)
|
||||
[SENSOR_PO2030] = 4,
|
||||
[SENSOR_TAS5130C] = 3,
|
||||
};
|
||||
|
||||
gspca_dev->vdev.ctrl_handler = hdl;
|
||||
v4l2_ctrl_handler_init(hdl, 8);
|
||||
sd->brightness = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
|
||||
V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
|
||||
sd->contrast = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
|
||||
V4L2_CID_CONTRAST, 0, 255, 1, 128);
|
||||
sd->gamma = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
|
||||
V4L2_CID_GAMMA, 1, 6, 1, gamma[sd->sensor]);
|
||||
if (sd->sensor == SENSOR_HV7131R)
|
||||
sd->exposure = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
|
||||
V4L2_CID_EXPOSURE, 0x30d, 0x493e, 1, 0x927);
|
||||
sd->autogain = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
|
||||
V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
|
||||
if (sd->sensor != SENSOR_OV7630C)
|
||||
sd->plfreq = v4l2_ctrl_new_std_menu(hdl, &zcxx_ctrl_ops,
|
||||
V4L2_CID_POWER_LINE_FREQUENCY,
|
||||
V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
|
||||
V4L2_CID_POWER_LINE_FREQUENCY_DISABLED);
|
||||
sd->sharpness = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
|
||||
V4L2_CID_SHARPNESS, 0, 3, 1,
|
||||
sd->sensor == SENSOR_PO2030 ? 0 : 2);
|
||||
sd->jpegqual = v4l2_ctrl_new_std(hdl, &zcxx_ctrl_ops,
|
||||
V4L2_CID_JPEG_COMPRESSION_QUALITY,
|
||||
jpeg_qual[0], jpeg_qual[ARRAY_SIZE(jpeg_qual) - 1], 1,
|
||||
jpeg_qual[REG08_DEF >> 1]);
|
||||
if (hdl->error) {
|
||||
pr_err("Could not initialize controls\n");
|
||||
return hdl->error;
|
||||
}
|
||||
v4l2_ctrl_cluster(3, &sd->gamma);
|
||||
if (sd->sensor == SENSOR_HV7131R)
|
||||
v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* this function is called at probe and resume time */
|
||||
static int sd_init(struct gspca_dev *gspca_dev)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
struct cam *cam;
|
||||
int sensor;
|
||||
static const u8 mode_tb[SENSOR_MAX] = {
|
||||
[SENSOR_ADCM2700] = 2,
|
||||
[SENSOR_CS2102] = 1,
|
||||
@ -6614,7 +6597,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
|
||||
case 0x2030:
|
||||
PDEBUG(D_PROBE, "Find Sensor PO2030");
|
||||
sd->sensor = SENSOR_PO2030;
|
||||
sd->ctrls[SHARPNESS].def = 0; /* from win traces */
|
||||
break;
|
||||
case 0x7620:
|
||||
PDEBUG(D_PROBE, "Find Sensor OV7620");
|
||||
@ -6656,26 +6638,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
|
||||
break;
|
||||
}
|
||||
|
||||
sd->ctrls[GAMMA].def = gamma[sd->sensor];
|
||||
sd->ctrls[QUALITY].def = jpeg_qual[sd->reg08 >> 1];
|
||||
sd->ctrls[QUALITY].min = jpeg_qual[0];
|
||||
sd->ctrls[QUALITY].max = jpeg_qual[ARRAY_SIZE(jpeg_qual) - 1];
|
||||
|
||||
switch (sd->sensor) {
|
||||
case SENSOR_HV7131R:
|
||||
break;
|
||||
case SENSOR_OV7630C:
|
||||
gspca_dev->ctrl_dis = (1 << LIGHTFREQ) | (1 << EXPOSURE);
|
||||
break;
|
||||
default:
|
||||
gspca_dev->ctrl_dis = (1 << EXPOSURE);
|
||||
break;
|
||||
}
|
||||
#if AUTOGAIN_DEF
|
||||
if (sd->ctrls[AUTOGAIN].val)
|
||||
gspca_dev->ctrl_inac = (1 << EXPOSURE);
|
||||
#endif
|
||||
|
||||
/* switch off the led */
|
||||
reg_w(gspca_dev, 0x01, 0x0000);
|
||||
return gspca_dev->usb_err;
|
||||
@ -6792,7 +6754,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
||||
reg_w(gspca_dev, 0x03, 0x0008);
|
||||
break;
|
||||
}
|
||||
setsharpness(gspca_dev);
|
||||
setsharpness(gspca_dev, v4l2_ctrl_g_ctrl(sd->sharpness));
|
||||
|
||||
/* set the gamma tables when not set */
|
||||
switch (sd->sensor) {
|
||||
@ -6801,7 +6763,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
||||
case SENSOR_OV7630C:
|
||||
break;
|
||||
default:
|
||||
setcontrast(gspca_dev);
|
||||
setcontrast(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma),
|
||||
v4l2_ctrl_g_ctrl(sd->brightness),
|
||||
v4l2_ctrl_g_ctrl(sd->contrast));
|
||||
break;
|
||||
}
|
||||
setmatrix(gspca_dev); /* one more time? */
|
||||
@ -6815,7 +6779,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
||||
setquality(gspca_dev);
|
||||
/* Start with BRC disabled, transfer_update will enable it if needed */
|
||||
reg_w(gspca_dev, 0x00, 0x0007);
|
||||
setlightfreq(gspca_dev);
|
||||
if (sd->plfreq)
|
||||
setlightfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->plfreq));
|
||||
|
||||
switch (sd->sensor) {
|
||||
case SENSOR_ADCM2700:
|
||||
@ -6826,7 +6791,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
||||
reg_w(gspca_dev, 0x40, 0x0117);
|
||||
break;
|
||||
case SENSOR_HV7131R:
|
||||
setexposure(gspca_dev);
|
||||
setexposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure));
|
||||
reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN);
|
||||
break;
|
||||
case SENSOR_GC0305:
|
||||
@ -6850,7 +6815,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
||||
break;
|
||||
}
|
||||
|
||||
setautogain(gspca_dev);
|
||||
setautogain(gspca_dev, v4l2_ctrl_g_ctrl(sd->autogain));
|
||||
|
||||
if (gspca_dev->usb_err < 0)
|
||||
return gspca_dev->usb_err;
|
||||
@ -6911,79 +6876,17 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|
||||
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
|
||||
}
|
||||
|
||||
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);
|
||||
if (gspca_dev->streaming)
|
||||
getexposure(gspca_dev);
|
||||
}
|
||||
if (gspca_dev->streaming)
|
||||
setautogain(gspca_dev);
|
||||
return gspca_dev->usb_err;
|
||||
}
|
||||
|
||||
static int sd_querymenu(struct gspca_dev *gspca_dev,
|
||||
struct v4l2_querymenu *menu)
|
||||
{
|
||||
switch (menu->id) {
|
||||
case V4L2_CID_POWER_LINE_FREQUENCY:
|
||||
switch (menu->index) {
|
||||
case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
|
||||
strcpy((char *) menu->name, "NoFliker");
|
||||
return 0;
|
||||
case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
|
||||
strcpy((char *) menu->name, "50 Hz");
|
||||
return 0;
|
||||
case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
|
||||
strcpy((char *) menu->name, "60 Hz");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int sd_setquality(struct gspca_dev *gspca_dev, __s32 val)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int i, qual = sd->reg08 >> 1;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(jpeg_qual); i++) {
|
||||
if (val <= jpeg_qual[i])
|
||||
break;
|
||||
}
|
||||
if (i > 0
|
||||
&& i == qual
|
||||
&& val < jpeg_qual[i])
|
||||
i--;
|
||||
|
||||
/* With high quality settings we need max bandwidth */
|
||||
if (i >= 2 && gspca_dev->streaming &&
|
||||
!gspca_dev->cam.needs_full_bandwidth)
|
||||
return -EBUSY;
|
||||
|
||||
sd->reg08 = (i << 1) | 1;
|
||||
sd->ctrls[QUALITY].val = jpeg_qual[i];
|
||||
|
||||
if (gspca_dev->streaming)
|
||||
setquality(gspca_dev);
|
||||
return gspca_dev->usb_err;
|
||||
}
|
||||
|
||||
static int sd_set_jcomp(struct gspca_dev *gspca_dev,
|
||||
struct v4l2_jpegcompression *jcomp)
|
||||
{
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
int ret;
|
||||
|
||||
sd_setquality(gspca_dev, jcomp->quality);
|
||||
jcomp->quality = sd->ctrls[QUALITY].val;
|
||||
return gspca_dev->usb_err;
|
||||
ret = v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
|
||||
if (ret)
|
||||
return ret;
|
||||
jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sd_get_jcomp(struct gspca_dev *gspca_dev,
|
||||
@ -6992,7 +6895,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
|
||||
struct sd *sd = (struct sd *) gspca_dev;
|
||||
|
||||
memset(jcomp, 0, sizeof *jcomp);
|
||||
jcomp->quality = sd->ctrls[QUALITY].val;
|
||||
jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
|
||||
jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
|
||||
| V4L2_JPEG_MARKER_DQT;
|
||||
return 0;
|
||||
@ -7016,15 +6919,13 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
|
||||
|
||||
static const struct sd_desc sd_desc = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.ctrls = sd_ctrls,
|
||||
.nctrls = ARRAY_SIZE(sd_ctrls),
|
||||
.config = sd_config,
|
||||
.init = sd_init,
|
||||
.init_controls = sd_init_controls,
|
||||
.isoc_init = sd_pre_start,
|
||||
.start = sd_start,
|
||||
.stop0 = sd_stop0,
|
||||
.pkt_scan = sd_pkt_scan,
|
||||
.querymenu = sd_querymenu,
|
||||
.get_jcomp = sd_get_jcomp,
|
||||
.set_jcomp = sd_set_jcomp,
|
||||
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
|
||||
@ -7108,6 +7009,7 @@ static struct usb_driver sd_driver = {
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = gspca_suspend,
|
||||
.resume = gspca_resume,
|
||||
.reset_resume = gspca_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user