[media] gspca_sonixj: Convert to the control framework
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
5ce60d790a
commit
c1f07ab2b3
|
@ -31,32 +31,26 @@ MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
|
||||||
MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
|
MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
/* controls */
|
|
||||||
enum e_ctrl {
|
|
||||||
BRIGHTNESS,
|
|
||||||
CONTRAST,
|
|
||||||
COLORS,
|
|
||||||
BLUE,
|
|
||||||
RED,
|
|
||||||
GAMMA,
|
|
||||||
EXPOSURE,
|
|
||||||
AUTOGAIN,
|
|
||||||
GAIN,
|
|
||||||
HFLIP,
|
|
||||||
VFLIP,
|
|
||||||
SHARPNESS,
|
|
||||||
ILLUM,
|
|
||||||
FREQ,
|
|
||||||
NCTRLS /* number of controls */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* specific webcam descriptor */
|
/* specific webcam descriptor */
|
||||||
struct sd {
|
struct sd {
|
||||||
struct gspca_dev gspca_dev; /* !! must be the first item */
|
struct gspca_dev gspca_dev; /* !! must be the first item */
|
||||||
|
|
||||||
struct gspca_ctrl ctrls[NCTRLS];
|
|
||||||
|
|
||||||
atomic_t avg_lum;
|
atomic_t avg_lum;
|
||||||
|
struct v4l2_ctrl *brightness;
|
||||||
|
struct v4l2_ctrl *contrast;
|
||||||
|
struct v4l2_ctrl *saturation;
|
||||||
|
struct { /* red/blue balance control cluster */
|
||||||
|
struct v4l2_ctrl *red_bal;
|
||||||
|
struct v4l2_ctrl *blue_bal;
|
||||||
|
};
|
||||||
|
struct { /* hflip/vflip control cluster */
|
||||||
|
struct v4l2_ctrl *vflip;
|
||||||
|
struct v4l2_ctrl *hflip;
|
||||||
|
};
|
||||||
|
struct v4l2_ctrl *gamma;
|
||||||
|
struct v4l2_ctrl *illum;
|
||||||
|
struct v4l2_ctrl *sharpness;
|
||||||
|
struct v4l2_ctrl *freq;
|
||||||
u32 exposure;
|
u32 exposure;
|
||||||
|
|
||||||
struct work_struct work;
|
struct work_struct work;
|
||||||
|
@ -127,283 +121,6 @@ static void qual_upd(struct work_struct *work);
|
||||||
#define SEN_CLK_EN 0x20 /* enable sensor clock */
|
#define SEN_CLK_EN 0x20 /* enable sensor clock */
|
||||||
#define DEF_EN 0x80 /* defect pixel by 0: soft, 1: hard */
|
#define DEF_EN 0x80 /* defect pixel by 0: soft, 1: hard */
|
||||||
|
|
||||||
/* V4L2 controls supported by the driver */
|
|
||||||
static void setbrightness(struct gspca_dev *gspca_dev);
|
|
||||||
static void setcontrast(struct gspca_dev *gspca_dev);
|
|
||||||
static void setcolors(struct gspca_dev *gspca_dev);
|
|
||||||
static void setredblue(struct gspca_dev *gspca_dev);
|
|
||||||
static void setgamma(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 setgain(struct gspca_dev *gspca_dev);
|
|
||||||
static void sethvflip(struct gspca_dev *gspca_dev);
|
|
||||||
static void setsharpness(struct gspca_dev *gspca_dev);
|
|
||||||
static void setillum(struct gspca_dev *gspca_dev);
|
|
||||||
static void setfreq(struct gspca_dev *gspca_dev);
|
|
||||||
|
|
||||||
static const struct ctrl sd_ctrls[NCTRLS] = {
|
|
||||||
[BRIGHTNESS] = {
|
|
||||||
{
|
|
||||||
.id = V4L2_CID_BRIGHTNESS,
|
|
||||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
||||||
.name = "Brightness",
|
|
||||||
.minimum = 0,
|
|
||||||
.maximum = 0xff,
|
|
||||||
.step = 1,
|
|
||||||
.default_value = 0x80,
|
|
||||||
},
|
|
||||||
.set_control = setbrightness
|
|
||||||
},
|
|
||||||
[CONTRAST] = {
|
|
||||||
{
|
|
||||||
.id = V4L2_CID_CONTRAST,
|
|
||||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
||||||
.name = "Contrast",
|
|
||||||
.minimum = 0,
|
|
||||||
#define CONTRAST_MAX 127
|
|
||||||
.maximum = CONTRAST_MAX,
|
|
||||||
.step = 1,
|
|
||||||
.default_value = 20,
|
|
||||||
},
|
|
||||||
.set_control = setcontrast
|
|
||||||
},
|
|
||||||
[COLORS] = {
|
|
||||||
{
|
|
||||||
.id = V4L2_CID_SATURATION,
|
|
||||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
||||||
.name = "Saturation",
|
|
||||||
.minimum = 0,
|
|
||||||
.maximum = 40,
|
|
||||||
.step = 1,
|
|
||||||
#define COLORS_DEF 25
|
|
||||||
.default_value = COLORS_DEF,
|
|
||||||
},
|
|
||||||
.set_control = setcolors
|
|
||||||
},
|
|
||||||
[BLUE] = {
|
|
||||||
{
|
|
||||||
.id = V4L2_CID_BLUE_BALANCE,
|
|
||||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
||||||
.name = "Blue Balance",
|
|
||||||
.minimum = 24,
|
|
||||||
.maximum = 40,
|
|
||||||
.step = 1,
|
|
||||||
.default_value = 32,
|
|
||||||
},
|
|
||||||
.set_control = setredblue
|
|
||||||
},
|
|
||||||
[RED] = {
|
|
||||||
{
|
|
||||||
.id = V4L2_CID_RED_BALANCE,
|
|
||||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
||||||
.name = "Red Balance",
|
|
||||||
.minimum = 24,
|
|
||||||
.maximum = 40,
|
|
||||||
.step = 1,
|
|
||||||
.default_value = 32,
|
|
||||||
},
|
|
||||||
.set_control = setredblue
|
|
||||||
},
|
|
||||||
[GAMMA] = {
|
|
||||||
{
|
|
||||||
.id = V4L2_CID_GAMMA,
|
|
||||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
||||||
.name = "Gamma",
|
|
||||||
.minimum = 0,
|
|
||||||
.maximum = 40,
|
|
||||||
.step = 1,
|
|
||||||
#define GAMMA_DEF 20
|
|
||||||
.default_value = GAMMA_DEF,
|
|
||||||
},
|
|
||||||
.set_control = setgamma
|
|
||||||
},
|
|
||||||
[EXPOSURE] = {
|
|
||||||
{
|
|
||||||
.id = V4L2_CID_EXPOSURE,
|
|
||||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
||||||
.name = "Exposure",
|
|
||||||
.minimum = 500,
|
|
||||||
.maximum = 1500,
|
|
||||||
.step = 1,
|
|
||||||
.default_value = 1024
|
|
||||||
},
|
|
||||||
.set_control = setexposure
|
|
||||||
},
|
|
||||||
[AUTOGAIN] = {
|
|
||||||
{
|
|
||||||
.id = V4L2_CID_AUTOGAIN,
|
|
||||||
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
|
||||||
.name = "Auto Gain",
|
|
||||||
.minimum = 0,
|
|
||||||
.maximum = 1,
|
|
||||||
.step = 1,
|
|
||||||
.default_value = 1
|
|
||||||
},
|
|
||||||
.set = sd_setautogain,
|
|
||||||
},
|
|
||||||
[GAIN] = {
|
|
||||||
{
|
|
||||||
.id = V4L2_CID_GAIN,
|
|
||||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
||||||
.name = "Gain",
|
|
||||||
.minimum = 4,
|
|
||||||
.maximum = 49,
|
|
||||||
.step = 1,
|
|
||||||
.default_value = 15
|
|
||||||
},
|
|
||||||
.set_control = setgain
|
|
||||||
},
|
|
||||||
[HFLIP] = {
|
|
||||||
{
|
|
||||||
.id = V4L2_CID_HFLIP,
|
|
||||||
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
|
||||||
.name = "Mirror",
|
|
||||||
.minimum = 0,
|
|
||||||
.maximum = 1,
|
|
||||||
.step = 1,
|
|
||||||
.default_value = 0,
|
|
||||||
},
|
|
||||||
.set_control = sethvflip
|
|
||||||
},
|
|
||||||
[VFLIP] = {
|
|
||||||
{
|
|
||||||
.id = V4L2_CID_VFLIP,
|
|
||||||
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
|
||||||
.name = "Vflip",
|
|
||||||
.minimum = 0,
|
|
||||||
.maximum = 1,
|
|
||||||
.step = 1,
|
|
||||||
.default_value = 0,
|
|
||||||
},
|
|
||||||
.set_control = sethvflip
|
|
||||||
},
|
|
||||||
[SHARPNESS] = {
|
|
||||||
{
|
|
||||||
.id = V4L2_CID_SHARPNESS,
|
|
||||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
||||||
.name = "Sharpness",
|
|
||||||
.minimum = 0,
|
|
||||||
.maximum = 255,
|
|
||||||
.step = 1,
|
|
||||||
.default_value = 90,
|
|
||||||
},
|
|
||||||
.set_control = setsharpness
|
|
||||||
},
|
|
||||||
[ILLUM] = {
|
|
||||||
{
|
|
||||||
.id = V4L2_CID_ILLUMINATORS_1,
|
|
||||||
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
|
||||||
.name = "Illuminator / infrared",
|
|
||||||
.minimum = 0,
|
|
||||||
.maximum = 1,
|
|
||||||
.step = 1,
|
|
||||||
.default_value = 0,
|
|
||||||
},
|
|
||||||
.set_control = setillum
|
|
||||||
},
|
|
||||||
/* ov7630/ov7648/ov7660 only */
|
|
||||||
[FREQ] = {
|
|
||||||
{
|
|
||||||
.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 = 1,
|
|
||||||
},
|
|
||||||
.set_control = setfreq
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
/* table of the disabled controls */
|
|
||||||
static const __u32 ctrl_dis[] = {
|
|
||||||
[SENSOR_ADCM1700] = (1 << EXPOSURE) |
|
|
||||||
(1 << AUTOGAIN) |
|
|
||||||
(1 << GAIN) |
|
|
||||||
(1 << HFLIP) |
|
|
||||||
(1 << VFLIP) |
|
|
||||||
(1 << FREQ),
|
|
||||||
|
|
||||||
[SENSOR_GC0307] = (1 << EXPOSURE) |
|
|
||||||
(1 << GAIN) |
|
|
||||||
(1 << HFLIP) |
|
|
||||||
(1 << VFLIP) |
|
|
||||||
(1 << FREQ),
|
|
||||||
|
|
||||||
[SENSOR_HV7131R] = (1 << EXPOSURE) |
|
|
||||||
(1 << GAIN) |
|
|
||||||
(1 << HFLIP) |
|
|
||||||
(1 << FREQ),
|
|
||||||
|
|
||||||
[SENSOR_MI0360] = (1 << EXPOSURE) |
|
|
||||||
(1 << GAIN) |
|
|
||||||
(1 << HFLIP) |
|
|
||||||
(1 << VFLIP) |
|
|
||||||
(1 << FREQ),
|
|
||||||
|
|
||||||
[SENSOR_MI0360B] = (1 << EXPOSURE) |
|
|
||||||
(1 << GAIN) |
|
|
||||||
(1 << HFLIP) |
|
|
||||||
(1 << VFLIP) |
|
|
||||||
(1 << FREQ),
|
|
||||||
|
|
||||||
[SENSOR_MO4000] = (1 << EXPOSURE) |
|
|
||||||
(1 << GAIN) |
|
|
||||||
(1 << HFLIP) |
|
|
||||||
(1 << VFLIP) |
|
|
||||||
(1 << FREQ),
|
|
||||||
|
|
||||||
[SENSOR_MT9V111] = (1 << EXPOSURE) |
|
|
||||||
(1 << GAIN) |
|
|
||||||
(1 << HFLIP) |
|
|
||||||
(1 << VFLIP) |
|
|
||||||
(1 << FREQ),
|
|
||||||
|
|
||||||
[SENSOR_OM6802] = (1 << EXPOSURE) |
|
|
||||||
(1 << GAIN) |
|
|
||||||
(1 << HFLIP) |
|
|
||||||
(1 << VFLIP) |
|
|
||||||
(1 << FREQ),
|
|
||||||
|
|
||||||
[SENSOR_OV7630] = (1 << EXPOSURE) |
|
|
||||||
(1 << GAIN) |
|
|
||||||
(1 << HFLIP),
|
|
||||||
|
|
||||||
[SENSOR_OV7648] = (1 << EXPOSURE) |
|
|
||||||
(1 << GAIN) |
|
|
||||||
(1 << HFLIP),
|
|
||||||
|
|
||||||
[SENSOR_OV7660] = (1 << EXPOSURE) |
|
|
||||||
(1 << AUTOGAIN) |
|
|
||||||
(1 << GAIN) |
|
|
||||||
(1 << HFLIP) |
|
|
||||||
(1 << VFLIP),
|
|
||||||
|
|
||||||
[SENSOR_PO1030] = (1 << EXPOSURE) |
|
|
||||||
(1 << AUTOGAIN) |
|
|
||||||
(1 << GAIN) |
|
|
||||||
(1 << HFLIP) |
|
|
||||||
(1 << VFLIP) |
|
|
||||||
(1 << FREQ),
|
|
||||||
|
|
||||||
[SENSOR_PO2030N] = (1 << FREQ),
|
|
||||||
|
|
||||||
[SENSOR_SOI768] = (1 << EXPOSURE) |
|
|
||||||
(1 << AUTOGAIN) |
|
|
||||||
(1 << GAIN) |
|
|
||||||
(1 << HFLIP) |
|
|
||||||
(1 << VFLIP) |
|
|
||||||
(1 << FREQ),
|
|
||||||
|
|
||||||
[SENSOR_SP80708] = (1 << EXPOSURE) |
|
|
||||||
(1 << AUTOGAIN) |
|
|
||||||
(1 << GAIN) |
|
|
||||||
(1 << HFLIP) |
|
|
||||||
(1 << VFLIP) |
|
|
||||||
(1 << FREQ),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct v4l2_pix_format cif_mode[] = {
|
static const struct v4l2_pix_format cif_mode[] = {
|
||||||
{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
|
{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
|
||||||
.bytesperline = 352,
|
.bytesperline = 352,
|
||||||
|
@ -1822,7 +1539,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
||||||
cam->nmodes = ARRAY_SIZE(vga_mode);
|
cam->nmodes = ARRAY_SIZE(vga_mode);
|
||||||
}
|
}
|
||||||
cam->npkt = 24; /* 24 packets per ISOC message */
|
cam->npkt = 24; /* 24 packets per ISOC message */
|
||||||
cam->ctrls = sd->ctrls;
|
|
||||||
|
|
||||||
sd->ag_cnt = -1;
|
sd->ag_cnt = -1;
|
||||||
sd->quality = QUALITY_DEF;
|
sd->quality = QUALITY_DEF;
|
||||||
|
@ -1888,9 +1604,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sd->sensor == SENSOR_OM6802)
|
|
||||||
sd->ctrls[SHARPNESS].def = 0x10;
|
|
||||||
|
|
||||||
/* Note we do not disable the sensor clock here (power saving mode),
|
/* Note we do not disable the sensor clock here (power saving mode),
|
||||||
as that also disables the button on the cam. */
|
as that also disables the button on the cam. */
|
||||||
reg_w1(gspca_dev, 0xf1, 0x00);
|
reg_w1(gspca_dev, 0xf1, 0x00);
|
||||||
|
@ -1899,13 +1612,92 @@ static int sd_init(struct gspca_dev *gspca_dev)
|
||||||
sn9c1xx = sn_tb[sd->sensor];
|
sn9c1xx = sn_tb[sd->sensor];
|
||||||
sd->i2c_addr = sn9c1xx[9];
|
sd->i2c_addr = sn9c1xx[9];
|
||||||
|
|
||||||
gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
|
|
||||||
if (!(sd->flags & F_ILLUM))
|
|
||||||
gspca_dev->ctrl_dis |= (1 << ILLUM);
|
|
||||||
|
|
||||||
return gspca_dev->usb_err;
|
return gspca_dev->usb_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sd_s_ctrl(struct v4l2_ctrl *ctrl);
|
||||||
|
|
||||||
|
static const struct v4l2_ctrl_ops sd_ctrl_ops = {
|
||||||
|
.s_ctrl = sd_s_ctrl,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* this function is called at probe time */
|
||||||
|
static int sd_init_controls(struct gspca_dev *gspca_dev)
|
||||||
|
{
|
||||||
|
struct sd *sd = (struct sd *) gspca_dev;
|
||||||
|
struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
|
||||||
|
|
||||||
|
gspca_dev->vdev.ctrl_handler = hdl;
|
||||||
|
v4l2_ctrl_handler_init(hdl, 14);
|
||||||
|
|
||||||
|
sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
|
||||||
|
V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
|
||||||
|
#define CONTRAST_MAX 127
|
||||||
|
sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
|
||||||
|
V4L2_CID_CONTRAST, 0, CONTRAST_MAX, 1, 20);
|
||||||
|
#define COLORS_DEF 25
|
||||||
|
sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
|
||||||
|
V4L2_CID_SATURATION, 0, 40, 1, COLORS_DEF);
|
||||||
|
sd->red_bal = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
|
||||||
|
V4L2_CID_RED_BALANCE, 24, 40, 1, 32);
|
||||||
|
sd->blue_bal = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
|
||||||
|
V4L2_CID_BLUE_BALANCE, 24, 40, 1, 32);
|
||||||
|
#define GAMMA_DEF 20
|
||||||
|
sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
|
||||||
|
V4L2_CID_GAMMA, 0, 40, 1, GAMMA_DEF);
|
||||||
|
|
||||||
|
if (sd->sensor == SENSOR_OM6802)
|
||||||
|
sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
|
||||||
|
V4L2_CID_SHARPNESS, 0, 255, 1, 16);
|
||||||
|
else
|
||||||
|
sd->sharpness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
|
||||||
|
V4L2_CID_SHARPNESS, 0, 255, 1, 90);
|
||||||
|
|
||||||
|
if (sd->flags & F_ILLUM)
|
||||||
|
sd->illum = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
|
||||||
|
V4L2_CID_ILLUMINATORS_1, 0, 1, 1, 0);
|
||||||
|
|
||||||
|
if (sd->sensor == SENSOR_PO2030N) {
|
||||||
|
gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
|
||||||
|
V4L2_CID_EXPOSURE, 500, 1500, 1, 1024);
|
||||||
|
gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
|
||||||
|
V4L2_CID_GAIN, 4, 49, 1, 15);
|
||||||
|
sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
|
||||||
|
V4L2_CID_HFLIP, 0, 1, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sd->sensor != SENSOR_ADCM1700 && sd->sensor != SENSOR_OV7660 &&
|
||||||
|
sd->sensor != SENSOR_PO1030 && sd->sensor != SENSOR_SOI768 &&
|
||||||
|
sd->sensor != SENSOR_SP80708)
|
||||||
|
gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
|
||||||
|
V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
|
||||||
|
|
||||||
|
if (sd->sensor == SENSOR_HV7131R || sd->sensor == SENSOR_OV7630 ||
|
||||||
|
sd->sensor == SENSOR_OV7648 || sd->sensor == SENSOR_PO2030N)
|
||||||
|
sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
|
||||||
|
V4L2_CID_VFLIP, 0, 1, 1, 0);
|
||||||
|
|
||||||
|
if (sd->sensor == SENSOR_OV7630 || sd->sensor == SENSOR_OV7648 ||
|
||||||
|
sd->sensor == SENSOR_OV7660)
|
||||||
|
sd->freq = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
|
||||||
|
V4L2_CID_POWER_LINE_FREQUENCY,
|
||||||
|
V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0,
|
||||||
|
V4L2_CID_POWER_LINE_FREQUENCY_50HZ);
|
||||||
|
|
||||||
|
if (hdl->error) {
|
||||||
|
pr_err("Could not initialize controls\n");
|
||||||
|
return hdl->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
v4l2_ctrl_cluster(2, &sd->red_bal);
|
||||||
|
if (sd->sensor == SENSOR_PO2030N) {
|
||||||
|
v4l2_ctrl_cluster(2, &sd->vflip);
|
||||||
|
v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static u32 expo_adjust(struct gspca_dev *gspca_dev,
|
static u32 expo_adjust(struct gspca_dev *gspca_dev,
|
||||||
u32 expo)
|
u32 expo)
|
||||||
{
|
{
|
||||||
|
@ -2014,10 +1806,9 @@ static void setbrightness(struct gspca_dev *gspca_dev)
|
||||||
{
|
{
|
||||||
struct sd *sd = (struct sd *) gspca_dev;
|
struct sd *sd = (struct sd *) gspca_dev;
|
||||||
unsigned int expo;
|
unsigned int expo;
|
||||||
int brightness;
|
int brightness = sd->brightness->val;
|
||||||
u8 k2;
|
u8 k2;
|
||||||
|
|
||||||
brightness = sd->ctrls[BRIGHTNESS].val;
|
|
||||||
k2 = (brightness - 0x80) >> 2;
|
k2 = (brightness - 0x80) >> 2;
|
||||||
switch (sd->sensor) {
|
switch (sd->sensor) {
|
||||||
case SENSOR_ADCM1700:
|
case SENSOR_ADCM1700:
|
||||||
|
@ -2064,7 +1855,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
|
||||||
u8 k2;
|
u8 k2;
|
||||||
u8 contrast[6];
|
u8 contrast[6];
|
||||||
|
|
||||||
k2 = sd->ctrls[CONTRAST].val * 37 / (CONTRAST_MAX + 1)
|
k2 = sd->contrast->val * 37 / (CONTRAST_MAX + 1)
|
||||||
+ 37; /* 37..73 */
|
+ 37; /* 37..73 */
|
||||||
contrast[0] = (k2 + 1) / 2; /* red */
|
contrast[0] = (k2 + 1) / 2; /* red */
|
||||||
contrast[1] = 0;
|
contrast[1] = 0;
|
||||||
|
@ -2090,7 +1881,7 @@ static void setcolors(struct gspca_dev *gspca_dev)
|
||||||
60, -51, -9 /* VR VG VB */
|
60, -51, -9 /* VR VG VB */
|
||||||
};
|
};
|
||||||
|
|
||||||
colors = sd->ctrls[COLORS].val;
|
colors = sd->saturation->val;
|
||||||
if (sd->sensor == SENSOR_MI0360B)
|
if (sd->sensor == SENSOR_MI0360B)
|
||||||
uv = uv_mi0360b;
|
uv = uv_mi0360b;
|
||||||
else
|
else
|
||||||
|
@ -2112,14 +1903,14 @@ static void setredblue(struct gspca_dev *gspca_dev)
|
||||||
{0xc1, 0x6e, 0x16, 0x00, 0x40, 0x00, 0x00, 0x10};
|
{0xc1, 0x6e, 0x16, 0x00, 0x40, 0x00, 0x00, 0x10};
|
||||||
|
|
||||||
/* 0x40 = normal value = gain x 1 */
|
/* 0x40 = normal value = gain x 1 */
|
||||||
rg1b[3] = sd->ctrls[RED].val * 2;
|
rg1b[3] = sd->red_bal->val * 2;
|
||||||
rg1b[5] = sd->ctrls[BLUE].val * 2;
|
rg1b[5] = sd->blue_bal->val * 2;
|
||||||
i2c_w8(gspca_dev, rg1b);
|
i2c_w8(gspca_dev, rg1b);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
reg_w1(gspca_dev, 0x05, sd->ctrls[RED].val);
|
reg_w1(gspca_dev, 0x05, sd->red_bal->val);
|
||||||
/* reg_w1(gspca_dev, 0x07, 32); */
|
/* reg_w1(gspca_dev, 0x07, 32); */
|
||||||
reg_w1(gspca_dev, 0x06, sd->ctrls[BLUE].val);
|
reg_w1(gspca_dev, 0x06, sd->blue_bal->val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setgamma(struct gspca_dev *gspca_dev)
|
static void setgamma(struct gspca_dev *gspca_dev)
|
||||||
|
@ -2153,7 +1944,7 @@ static void setgamma(struct gspca_dev *gspca_dev)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
val = sd->ctrls[GAMMA].val;
|
val = sd->gamma->val;
|
||||||
for (i = 0; i < sizeof gamma; i++)
|
for (i = 0; i < sizeof gamma; i++)
|
||||||
gamma[i] = gamma_base[i]
|
gamma[i] = gamma_base[i]
|
||||||
+ delta[i] * (val - GAMMA_DEF) / 32;
|
+ delta[i] * (val - GAMMA_DEF) / 32;
|
||||||
|
@ -2168,11 +1959,11 @@ static void setexposure(struct gspca_dev *gspca_dev)
|
||||||
u8 rexpo[] = /* 1a: expo H, 1b: expo M */
|
u8 rexpo[] = /* 1a: expo H, 1b: expo M */
|
||||||
{0xa1, 0x6e, 0x1a, 0x00, 0x40, 0x00, 0x00, 0x10};
|
{0xa1, 0x6e, 0x1a, 0x00, 0x40, 0x00, 0x00, 0x10};
|
||||||
|
|
||||||
rexpo[3] = sd->ctrls[EXPOSURE].val >> 8;
|
rexpo[3] = gspca_dev->exposure->val >> 8;
|
||||||
i2c_w8(gspca_dev, rexpo);
|
i2c_w8(gspca_dev, rexpo);
|
||||||
msleep(6);
|
msleep(6);
|
||||||
rexpo[2] = 0x1b;
|
rexpo[2] = 0x1b;
|
||||||
rexpo[3] = sd->ctrls[EXPOSURE].val;
|
rexpo[3] = gspca_dev->exposure->val;
|
||||||
i2c_w8(gspca_dev, rexpo);
|
i2c_w8(gspca_dev, rexpo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2181,8 +1972,6 @@ static void setautogain(struct gspca_dev *gspca_dev)
|
||||||
{
|
{
|
||||||
struct sd *sd = (struct sd *) gspca_dev;
|
struct sd *sd = (struct sd *) gspca_dev;
|
||||||
|
|
||||||
if (gspca_dev->ctrl_dis & (1 << AUTOGAIN))
|
|
||||||
return;
|
|
||||||
switch (sd->sensor) {
|
switch (sd->sensor) {
|
||||||
case SENSOR_OV7630:
|
case SENSOR_OV7630:
|
||||||
case SENSOR_OV7648: {
|
case SENSOR_OV7648: {
|
||||||
|
@ -2192,13 +1981,13 @@ static void setautogain(struct gspca_dev *gspca_dev)
|
||||||
comb = 0xc0;
|
comb = 0xc0;
|
||||||
else
|
else
|
||||||
comb = 0xa0;
|
comb = 0xa0;
|
||||||
if (sd->ctrls[AUTOGAIN].val)
|
if (gspca_dev->autogain->val)
|
||||||
comb |= 0x03;
|
comb |= 0x03;
|
||||||
i2c_w1(&sd->gspca_dev, 0x13, comb);
|
i2c_w1(&sd->gspca_dev, 0x13, comb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sd->ctrls[AUTOGAIN].val)
|
if (gspca_dev->autogain->val)
|
||||||
sd->ag_cnt = AG_CNT_START;
|
sd->ag_cnt = AG_CNT_START;
|
||||||
else
|
else
|
||||||
sd->ag_cnt = -1;
|
sd->ag_cnt = -1;
|
||||||
|
@ -2212,7 +2001,7 @@ static void setgain(struct gspca_dev *gspca_dev)
|
||||||
u8 rgain[] = /* 15: gain */
|
u8 rgain[] = /* 15: gain */
|
||||||
{0xa1, 0x6e, 0x15, 0x00, 0x40, 0x00, 0x00, 0x15};
|
{0xa1, 0x6e, 0x15, 0x00, 0x40, 0x00, 0x00, 0x15};
|
||||||
|
|
||||||
rgain[3] = sd->ctrls[GAIN].val;
|
rgain[3] = gspca_dev->gain->val;
|
||||||
i2c_w8(gspca_dev, rgain);
|
i2c_w8(gspca_dev, rgain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2225,19 +2014,19 @@ static void sethvflip(struct gspca_dev *gspca_dev)
|
||||||
switch (sd->sensor) {
|
switch (sd->sensor) {
|
||||||
case SENSOR_HV7131R:
|
case SENSOR_HV7131R:
|
||||||
comn = 0x18; /* clkdiv = 1, ablcen = 1 */
|
comn = 0x18; /* clkdiv = 1, ablcen = 1 */
|
||||||
if (sd->ctrls[VFLIP].val)
|
if (sd->vflip->val)
|
||||||
comn |= 0x01;
|
comn |= 0x01;
|
||||||
i2c_w1(gspca_dev, 0x01, comn); /* sctra */
|
i2c_w1(gspca_dev, 0x01, comn); /* sctra */
|
||||||
break;
|
break;
|
||||||
case SENSOR_OV7630:
|
case SENSOR_OV7630:
|
||||||
comn = 0x02;
|
comn = 0x02;
|
||||||
if (!sd->ctrls[VFLIP].val)
|
if (!sd->vflip->val)
|
||||||
comn |= 0x80;
|
comn |= 0x80;
|
||||||
i2c_w1(gspca_dev, 0x75, comn);
|
i2c_w1(gspca_dev, 0x75, comn);
|
||||||
break;
|
break;
|
||||||
case SENSOR_OV7648:
|
case SENSOR_OV7648:
|
||||||
comn = 0x06;
|
comn = 0x06;
|
||||||
if (sd->ctrls[VFLIP].val)
|
if (sd->vflip->val)
|
||||||
comn |= 0x80;
|
comn |= 0x80;
|
||||||
i2c_w1(gspca_dev, 0x75, comn);
|
i2c_w1(gspca_dev, 0x75, comn);
|
||||||
break;
|
break;
|
||||||
|
@ -2251,9 +2040,9 @@ static void sethvflip(struct gspca_dev *gspca_dev)
|
||||||
* bit3-0: X
|
* bit3-0: X
|
||||||
*/
|
*/
|
||||||
comn = 0x0a;
|
comn = 0x0a;
|
||||||
if (sd->ctrls[HFLIP].val)
|
if (sd->hflip->val)
|
||||||
comn |= 0x80;
|
comn |= 0x80;
|
||||||
if (sd->ctrls[VFLIP].val)
|
if (sd->vflip->val)
|
||||||
comn |= 0x40;
|
comn |= 0x40;
|
||||||
i2c_w1(&sd->gspca_dev, 0x1e, comn);
|
i2c_w1(&sd->gspca_dev, 0x1e, comn);
|
||||||
break;
|
break;
|
||||||
|
@ -2264,23 +2053,21 @@ static void setsharpness(struct gspca_dev *gspca_dev)
|
||||||
{
|
{
|
||||||
struct sd *sd = (struct sd *) gspca_dev;
|
struct sd *sd = (struct sd *) gspca_dev;
|
||||||
|
|
||||||
reg_w1(gspca_dev, 0x99, sd->ctrls[SHARPNESS].val);
|
reg_w1(gspca_dev, 0x99, sd->sharpness->val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setillum(struct gspca_dev *gspca_dev)
|
static void setillum(struct gspca_dev *gspca_dev)
|
||||||
{
|
{
|
||||||
struct sd *sd = (struct sd *) gspca_dev;
|
struct sd *sd = (struct sd *) gspca_dev;
|
||||||
|
|
||||||
if (gspca_dev->ctrl_dis & (1 << ILLUM))
|
|
||||||
return;
|
|
||||||
switch (sd->sensor) {
|
switch (sd->sensor) {
|
||||||
case SENSOR_ADCM1700:
|
case SENSOR_ADCM1700:
|
||||||
reg_w1(gspca_dev, 0x02, /* gpio */
|
reg_w1(gspca_dev, 0x02, /* gpio */
|
||||||
sd->ctrls[ILLUM].val ? 0x64 : 0x60);
|
sd->illum->val ? 0x64 : 0x60);
|
||||||
break;
|
break;
|
||||||
case SENSOR_MT9V111:
|
case SENSOR_MT9V111:
|
||||||
reg_w1(gspca_dev, 0x02,
|
reg_w1(gspca_dev, 0x02,
|
||||||
sd->ctrls[ILLUM].val ? 0x77 : 0x74);
|
sd->illum->val ? 0x77 : 0x74);
|
||||||
/* should have been: */
|
/* should have been: */
|
||||||
/* 0x55 : 0x54); * 370i */
|
/* 0x55 : 0x54); * 370i */
|
||||||
/* 0x66 : 0x64); * Clip */
|
/* 0x66 : 0x64); * Clip */
|
||||||
|
@ -2292,13 +2079,11 @@ static void setfreq(struct gspca_dev *gspca_dev)
|
||||||
{
|
{
|
||||||
struct sd *sd = (struct sd *) gspca_dev;
|
struct sd *sd = (struct sd *) gspca_dev;
|
||||||
|
|
||||||
if (gspca_dev->ctrl_dis & (1 << FREQ))
|
|
||||||
return;
|
|
||||||
if (sd->sensor == SENSOR_OV7660) {
|
if (sd->sensor == SENSOR_OV7660) {
|
||||||
u8 com8;
|
u8 com8;
|
||||||
|
|
||||||
com8 = 0xdf; /* auto gain/wb/expo */
|
com8 = 0xdf; /* auto gain/wb/expo */
|
||||||
switch (sd->ctrls[FREQ].val) {
|
switch (sd->freq->val) {
|
||||||
case 0: /* Banding filter disabled */
|
case 0: /* Banding filter disabled */
|
||||||
i2c_w1(gspca_dev, 0x13, com8 | 0x20);
|
i2c_w1(gspca_dev, 0x13, com8 | 0x20);
|
||||||
break;
|
break;
|
||||||
|
@ -2326,7 +2111,7 @@ static void setfreq(struct gspca_dev *gspca_dev)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (sd->ctrls[FREQ].val) {
|
switch (sd->freq->val) {
|
||||||
case 0: /* Banding filter disabled */
|
case 0: /* Banding filter disabled */
|
||||||
break;
|
break;
|
||||||
case 1: /* 50 hz (filter on and framerate adj) */
|
case 1: /* 50 hz (filter on and framerate adj) */
|
||||||
|
@ -2698,17 +2483,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
||||||
sd->reg01 = reg01;
|
sd->reg01 = reg01;
|
||||||
sd->reg17 = reg17;
|
sd->reg17 = reg17;
|
||||||
|
|
||||||
sethvflip(gspca_dev);
|
|
||||||
setbrightness(gspca_dev);
|
|
||||||
setcontrast(gspca_dev);
|
|
||||||
setcolors(gspca_dev);
|
|
||||||
setautogain(gspca_dev);
|
|
||||||
if (!(gspca_dev->ctrl_inac & ((1 << EXPOSURE) | (1 << GAIN)))) {
|
|
||||||
setexposure(gspca_dev);
|
|
||||||
setgain(gspca_dev);
|
|
||||||
}
|
|
||||||
setfreq(gspca_dev);
|
|
||||||
|
|
||||||
sd->pktsz = sd->npkt = 0;
|
sd->pktsz = sd->npkt = 0;
|
||||||
sd->nchg = sd->short_mark = 0;
|
sd->nchg = sd->short_mark = 0;
|
||||||
sd->work_thread = create_singlethread_workqueue(MODULE_NAME);
|
sd->work_thread = create_singlethread_workqueue(MODULE_NAME);
|
||||||
|
@ -2803,9 +2577,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define WANT_REGULAR_AUTOGAIN
|
|
||||||
#include "autogain_functions.h"
|
|
||||||
|
|
||||||
static void do_autogain(struct gspca_dev *gspca_dev)
|
static void do_autogain(struct gspca_dev *gspca_dev)
|
||||||
{
|
{
|
||||||
struct sd *sd = (struct sd *) gspca_dev;
|
struct sd *sd = (struct sd *) gspca_dev;
|
||||||
|
@ -2825,7 +2596,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
|
||||||
PDEBUG(D_FRAM, "mean lum %d", delta);
|
PDEBUG(D_FRAM, "mean lum %d", delta);
|
||||||
|
|
||||||
if (sd->sensor == SENSOR_PO2030N) {
|
if (sd->sensor == SENSOR_PO2030N) {
|
||||||
auto_gain_n_exposure(gspca_dev, delta, luma_mean, luma_delta,
|
gspca_expo_autogain(gspca_dev, delta, luma_mean, luma_delta,
|
||||||
15, 1024);
|
15, 1024);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3042,39 +2813,53 @@ marker_found:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
|
static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||||
{
|
{
|
||||||
struct sd *sd = (struct sd *) gspca_dev;
|
struct gspca_dev *gspca_dev =
|
||||||
|
container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
|
||||||
|
|
||||||
sd->ctrls[AUTOGAIN].val = val;
|
gspca_dev->usb_err = 0;
|
||||||
if (val)
|
|
||||||
gspca_dev->ctrl_inac |= (1 << EXPOSURE) | (1 << GAIN);
|
|
||||||
else
|
|
||||||
gspca_dev->ctrl_inac &= ~(1 << EXPOSURE) & ~(1 << GAIN);
|
|
||||||
if (gspca_dev->streaming)
|
|
||||||
setautogain(gspca_dev);
|
|
||||||
return gspca_dev->usb_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sd_querymenu(struct gspca_dev *gspca_dev,
|
if (!gspca_dev->streaming)
|
||||||
struct v4l2_querymenu *menu)
|
return 0;
|
||||||
{
|
|
||||||
switch (menu->id) {
|
switch (ctrl->id) {
|
||||||
case V4L2_CID_POWER_LINE_FREQUENCY:
|
case V4L2_CID_BRIGHTNESS:
|
||||||
switch (menu->index) {
|
setbrightness(gspca_dev);
|
||||||
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;
|
break;
|
||||||
|
case V4L2_CID_CONTRAST:
|
||||||
|
setcontrast(gspca_dev);
|
||||||
|
break;
|
||||||
|
case V4L2_CID_SATURATION:
|
||||||
|
setcolors(gspca_dev);
|
||||||
|
break;
|
||||||
|
case V4L2_CID_RED_BALANCE:
|
||||||
|
setredblue(gspca_dev);
|
||||||
|
break;
|
||||||
|
case V4L2_CID_GAMMA:
|
||||||
|
setgamma(gspca_dev);
|
||||||
|
break;
|
||||||
|
case V4L2_CID_AUTOGAIN:
|
||||||
|
setautogain(gspca_dev);
|
||||||
|
setexposure(gspca_dev);
|
||||||
|
setgain(gspca_dev);
|
||||||
|
break;
|
||||||
|
case V4L2_CID_VFLIP:
|
||||||
|
sethvflip(gspca_dev);
|
||||||
|
break;
|
||||||
|
case V4L2_CID_SHARPNESS:
|
||||||
|
setsharpness(gspca_dev);
|
||||||
|
break;
|
||||||
|
case V4L2_CID_ILLUMINATORS_1:
|
||||||
|
setillum(gspca_dev);
|
||||||
|
break;
|
||||||
|
case V4L2_CID_POWER_LINE_FREQUENCY:
|
||||||
|
setfreq(gspca_dev);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
return -EINVAL;
|
return gspca_dev->usb_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_INPUT)
|
#if IS_ENABLED(CONFIG_INPUT)
|
||||||
|
@ -3099,16 +2884,14 @@ static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
|
||||||
/* sub-driver description */
|
/* sub-driver description */
|
||||||
static const struct sd_desc sd_desc = {
|
static const struct sd_desc sd_desc = {
|
||||||
.name = MODULE_NAME,
|
.name = MODULE_NAME,
|
||||||
.ctrls = sd_ctrls,
|
|
||||||
.nctrls = NCTRLS,
|
|
||||||
.config = sd_config,
|
.config = sd_config,
|
||||||
.init = sd_init,
|
.init = sd_init,
|
||||||
|
.init_controls = sd_init_controls,
|
||||||
.start = sd_start,
|
.start = sd_start,
|
||||||
.stopN = sd_stopN,
|
.stopN = sd_stopN,
|
||||||
.stop0 = sd_stop0,
|
.stop0 = sd_stop0,
|
||||||
.pkt_scan = sd_pkt_scan,
|
.pkt_scan = sd_pkt_scan,
|
||||||
.dq_callback = do_autogain,
|
.dq_callback = do_autogain,
|
||||||
.querymenu = sd_querymenu,
|
|
||||||
#if IS_ENABLED(CONFIG_INPUT)
|
#if IS_ENABLED(CONFIG_INPUT)
|
||||||
.int_pkt_scan = sd_int_pkt_scan,
|
.int_pkt_scan = sd_int_pkt_scan,
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue