* are getting "Failed to read sensor ID..." */
static int i2c_detect_tries = 10;
+/* controls */
+enum e_ctrl {
+ BRIGHTNESS,
+ CONTRAST,
+ COLORS,
+ HFLIP,
+ VFLIP,
+ AUTOBRIGHT,
+ FREQ,
+ NCTRL /* number of controls */
+};
+
/* ov519 device descriptor */
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
+ struct gspca_ctrl ctrls[NCTRL];
+
__u8 packet_nr;
char bridge;
/* Determined by sensor type */
__u8 sif;
- __u8 brightness;
- __u8 contrast;
- __u8 colors;
- __u8 hflip;
- __u8 vflip;
- __u8 autobrightness;
- __u8 freq;
__u8 quality;
#define QUALITY_MIN 50
#define QUALITY_MAX 70
#include "w996Xcf.c"
/* 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_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setautobrightness(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getautobrightness(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 setbrightness(struct gspca_dev *gspca_dev);
static void setcontrast(struct gspca_dev *gspca_dev);
static void setcolors(struct gspca_dev *gspca_dev);
-static void setautobrightness(struct sd *sd);
-static void setfreq(struct sd *sd);
+static void sethvflip(struct gspca_dev *gspca_dev);
+static void setautobright(struct gspca_dev *gspca_dev);
+static void setfreq(struct gspca_dev *gspca_dev);
+static void setfreq_i(struct sd *sd);
static const struct ctrl sd_ctrls[] = {
-#define BRIGHTNESS_IDX 0
- {
+[BRIGHTNESS] = {
{
.id = V4L2_CID_BRIGHTNESS,
.type = V4L2_CTRL_TYPE_INTEGER,
.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 CONTRAST_IDX 1
- {
+[CONTRAST] = {
{
.id = V4L2_CID_CONTRAST,
.type = V4L2_CTRL_TYPE_INTEGER,
.minimum = 0,
.maximum = 255,
.step = 1,
-#define CONTRAST_DEF 127
- .default_value = CONTRAST_DEF,
+ .default_value = 127,
},
- .set = sd_setcontrast,
- .get = sd_getcontrast,
+ .set_control = setcontrast,
},
-#define COLOR_IDX 2
- {
+[COLORS] = {
{
.id = V4L2_CID_SATURATION,
.type = V4L2_CTRL_TYPE_INTEGER,
.minimum = 0,
.maximum = 255,
.step = 1,
-#define COLOR_DEF 127
- .default_value = COLOR_DEF,
+ .default_value = 127,
},
- .set = sd_setcolors,
- .get = sd_getcolors,
+ .set_control = setcolors,
},
/* The flip controls work with ov7670 only */
-#define HFLIP_IDX 3
- {
+[HFLIP] = {
{
.id = V4L2_CID_HFLIP,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.minimum = 0,
.maximum = 1,
.step = 1,
-#define HFLIP_DEF 0
- .default_value = HFLIP_DEF,
+ .default_value = 0,
},
- .set = sd_sethflip,
- .get = sd_gethflip,
+ .set_control = sethvflip,
},
-#define VFLIP_IDX 4
- {
+[VFLIP] = {
{
.id = V4L2_CID_VFLIP,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.minimum = 0,
.maximum = 1,
.step = 1,
-#define VFLIP_DEF 0
- .default_value = VFLIP_DEF,
+ .default_value = 0,
},
- .set = sd_setvflip,
- .get = sd_getvflip,
+ .set_control = sethvflip,
},
-#define AUTOBRIGHT_IDX 5
- {
+[AUTOBRIGHT] = {
{
.id = V4L2_CID_AUTOBRIGHTNESS,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.minimum = 0,
.maximum = 1,
.step = 1,
-#define AUTOBRIGHT_DEF 1
- .default_value = AUTOBRIGHT_DEF,
+ .default_value = 1,
},
- .set = sd_setautobrightness,
- .get = sd_getautobrightness,
+ .set_control = setautobright,
},
-#define FREQ_IDX 6
- {
+[FREQ] = {
{
.id = V4L2_CID_POWER_LINE_FREQUENCY,
.type = V4L2_CTRL_TYPE_MENU,
.minimum = 0,
.maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
.step = 1,
-#define FREQ_DEF 0
- .default_value = FREQ_DEF,
- },
- .set = sd_setfreq,
- .get = sd_getfreq,
- },
-#define OV7670_FREQ_IDX 7
- {
- {
- .id = V4L2_CID_POWER_LINE_FREQUENCY,
- .type = V4L2_CTRL_TYPE_MENU,
- .name = "Light frequency filter",
- .minimum = 0,
- .maximum = 3, /* 0: 0, 1: 50Hz, 2:60Hz 3: Auto Hz */
- .step = 1,
-#define OV7670_FREQ_DEF 3
- .default_value = OV7670_FREQ_DEF,
+ .default_value = 0,
},
- .set = sd_setfreq,
- .get = sd_getfreq,
+ .set_control = setfreq,
},
};
goto error;
break;
}
- sd->brightness = BRIGHTNESS_DEF;
- if (sd->sensor == SEN_OV6630 || sd->sensor == SEN_OV66308AF)
- sd->contrast = 200; /* The default is too low for the ov6630 */
+ gspca_dev->cam.ctrls = sd->ctrls;
+ if (sd->sensor == SEN_OV7670)
+ gspca_dev->ctrl_dis = 1 << COLORS;
else
- sd->contrast = CONTRAST_DEF;
- sd->colors = COLOR_DEF;
- sd->hflip = HFLIP_DEF;
- sd->vflip = VFLIP_DEF;
- sd->autobrightness = AUTOBRIGHT_DEF;
- if (sd->sensor == SEN_OV7670) {
- sd->freq = OV7670_FREQ_DEF;
- gspca_dev->ctrl_dis = (1 << FREQ_IDX) | (1 << COLOR_IDX);
- } else {
- sd->freq = FREQ_DEF;
- gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) |
- (1 << OV7670_FREQ_IDX);
- }
+ gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
sd->quality = QUALITY_DEF;
if (sd->sensor == SEN_OV7640 ||
sd->sensor == SEN_OV7648)
- gspca_dev->ctrl_dis |= (1 << AUTOBRIGHT_IDX) |
- (1 << CONTRAST_IDX);
+ gspca_dev->ctrl_dis |= (1 << AUTOBRIGHT) | (1 << CONTRAST);
if (sd->sensor == SEN_OV7670)
- gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT_IDX;
+ gspca_dev->ctrl_dis |= 1 << AUTOBRIGHT;
/* OV8610 Frequency filter control should work but needs testing */
if (sd->sensor == SEN_OV8610)
- gspca_dev->ctrl_dis |= 1 << FREQ_IDX;
+ gspca_dev->ctrl_dis |= 1 << FREQ;
/* No controls for the OV2610/OV3610 */
if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
- gspca_dev->ctrl_dis |= 0xFF;
+ gspca_dev->ctrl_dis |= (1 << NCTRL) - 1;
return 0;
error:
break;
case SEN_OV6630:
case SEN_OV66308AF:
+ sd->ctrls[CONTRAST].def = 200;
+ /* The default is too low for the ov6630 */
if (write_i2c_regvals(sd, norm_6x30, ARRAY_SIZE(norm_6x30)))
return -EIO;
break;
return -EIO;
break;
case SEN_OV7670:
+ sd->ctrls[FREQ].max = 3; /* auto */
+ sd->ctrls[FREQ].def = 3;
if (write_i2c_regvals(sd, norm_7670, ARRAY_SIZE(norm_7670)))
return -EIO;
break;
return 0;
}
-static void sethvflip(struct sd *sd)
+static void sethvflip(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
+
if (sd->sensor != SEN_OV7670)
return;
if (sd->gspca_dev.streaming)
ov51x_stop(sd);
i2c_w_mask(sd, OV7670_REG_MVFP,
- OV7670_MVFP_MIRROR * sd->hflip
- | OV7670_MVFP_VFLIP * sd->vflip,
+ OV7670_MVFP_MIRROR * sd->ctrls[HFLIP].val
+ | OV7670_MVFP_VFLIP * sd->ctrls[VFLIP].val,
OV7670_MVFP_MIRROR | OV7670_MVFP_VFLIP);
if (sd->gspca_dev.streaming)
ov51x_restart(sd);
setcontrast(gspca_dev);
setbrightness(gspca_dev);
setcolors(gspca_dev);
- sethvflip(sd);
- setautobrightness(sd);
- setfreq(sd);
+ sethvflip(gspca_dev);
+ setautobright(gspca_dev);
+ setfreq_i(sd);
/* Force clear snapshot state in case the snapshot button was
pressed while we weren't streaming */
struct sd *sd = (struct sd *) gspca_dev;
int val;
- val = sd->brightness;
+ val = sd->ctrls[BRIGHTNESS].val;
switch (sd->sensor) {
case SEN_OV8610:
case SEN_OV7610:
case SEN_OV7620:
case SEN_OV7620AE:
/* 7620 doesn't like manual changes when in auto mode */
- if (!sd->autobrightness)
+ if (!sd->ctrls[AUTOBRIGHT].val)
i2c_w(sd, OV7610_REG_BRT, val);
break;
case SEN_OV7670:
struct sd *sd = (struct sd *) gspca_dev;
int val;
- val = sd->contrast;
+ val = sd->ctrls[CONTRAST].val;
switch (sd->sensor) {
case SEN_OV7610:
case SEN_OV6620:
struct sd *sd = (struct sd *) gspca_dev;
int val;
- val = sd->colors;
+ val = sd->ctrls[COLORS].val;
switch (sd->sensor) {
case SEN_OV8610:
case SEN_OV7610:
}
}
-static void setautobrightness(struct sd *sd)
+static void setautobright(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
+
if (sd->sensor == SEN_OV7640 || sd->sensor == SEN_OV7648 ||
sd->sensor == SEN_OV7670 ||
sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
return;
- i2c_w_mask(sd, 0x2d, sd->autobrightness ? 0x10 : 0x00, 0x10);
+ i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10);
}
-static void setfreq(struct sd *sd)
+static void setfreq_i(struct sd *sd)
{
if (sd->sensor == SEN_OV2610 || sd->sensor == SEN_OV3610)
return;
if (sd->sensor == SEN_OV7670) {
- switch (sd->freq) {
+ switch (sd->ctrls[FREQ].val) {
case 0: /* Banding filter disabled */
i2c_w_mask(sd, OV7670_REG_COM8, 0, OV7670_COM8_BFILT);
break;
break;
}
} else {
- switch (sd->freq) {
+ switch (sd->ctrls[FREQ].val) {
case 0: /* Banding filter disabled */
i2c_w_mask(sd, 0x2d, 0x00, 0x04);
i2c_w_mask(sd, 0x2a, 0x00, 0x80);
}
}
}
-
-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_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->contrast = val;
- if (gspca_dev->streaming)
- setcontrast(gspca_dev);
- return 0;
-}
-
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->contrast;
- return 0;
-}
-
-static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->colors = val;
- if (gspca_dev->streaming)
- setcolors(gspca_dev);
- return 0;
-}
-
-static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->colors;
- return 0;
-}
-
-static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
+static void setfreq(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- sd->hflip = val;
- if (gspca_dev->streaming)
- sethvflip(sd);
- return 0;
-}
-
-static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
+ setfreq_i(sd);
- *val = sd->hflip;
- return 0;
-}
-
-static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->vflip = val;
- if (gspca_dev->streaming)
- sethvflip(sd);
- return 0;
-}
-
-static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->vflip;
- return 0;
-}
-
-static int sd_setautobrightness(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->autobrightness = val;
- if (gspca_dev->streaming)
- setautobrightness(sd);
- return 0;
-}
-
-static int sd_getautobrightness(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->autobrightness;
- 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(sd);
- /* Ugly but necessary */
- if (sd->bridge == BRIDGE_W9968CF)
- w9968cf_set_crop_window(sd);
- }
- 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;
+ /* Ugly but necessary */
+ if (sd->bridge == BRIDGE_W9968CF)
+ w9968cf_set_crop_window(sd);
}
static int sd_querymenu(struct gspca_dev *gspca_dev,