From: Antonio Ospite Date: Wed, 16 May 2012 21:42:46 +0000 (-0300) Subject: [media] gspca_ov534: Convert to the control framework X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=1bd7d6adc691993206cf7dd69f1aaf8dccb06677;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git [media] gspca_ov534: Convert to the control framework Signed-off-by: Antonio Ospite Signed-off-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 80c81dd6d68b..78d11dd67817 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -35,6 +35,7 @@ #include "gspca.h" #include +#include #define OV534_REG_ADDRESS 0xf1 /* sensor address */ #define OV534_REG_SUBADDR 0xf2 @@ -53,29 +54,28 @@ MODULE_AUTHOR("Antonio Ospite "); MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver"); MODULE_LICENSE("GPL"); -/* controls */ -enum e_ctrl { - HUE, - SATURATION, - BRIGHTNESS, - CONTRAST, - GAIN, - EXPOSURE, - AGC, - AWB, - AEC, - SHARPNESS, - HFLIP, - VFLIP, - LIGHTFREQ, - NCTRLS /* number of controls */ -}; - /* 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 v4l2_ctrl *hue; + struct v4l2_ctrl *saturation; + struct v4l2_ctrl *brightness; + struct v4l2_ctrl *contrast; + struct { /* gain control cluster */ + struct v4l2_ctrl *autogain; + struct v4l2_ctrl *gain; + }; + struct v4l2_ctrl *autowhitebalance; + struct { /* exposure control cluster */ + struct v4l2_ctrl *autoexposure; + struct v4l2_ctrl *exposure; + }; + struct v4l2_ctrl *sharpness; + struct v4l2_ctrl *hflip; + struct v4l2_ctrl *vflip; + struct v4l2_ctrl *plfreq; __u32 last_pts; u16 last_fid; @@ -89,181 +89,9 @@ enum sensors { NSENSORS }; -/* V4L2 controls supported by the driver */ -static void sethue(struct gspca_dev *gspca_dev); -static void setsaturation(struct gspca_dev *gspca_dev); -static void setbrightness(struct gspca_dev *gspca_dev); -static void setcontrast(struct gspca_dev *gspca_dev); -static void setgain(struct gspca_dev *gspca_dev); -static void setexposure(struct gspca_dev *gspca_dev); -static void setagc(struct gspca_dev *gspca_dev); -static void setawb(struct gspca_dev *gspca_dev); -static void setaec(struct gspca_dev *gspca_dev); -static void setsharpness(struct gspca_dev *gspca_dev); -static void sethvflip(struct gspca_dev *gspca_dev); -static void setlightfreq(struct gspca_dev *gspca_dev); - static int sd_start(struct gspca_dev *gspca_dev); static void sd_stopN(struct gspca_dev *gspca_dev); -static const struct ctrl sd_ctrls[] = { -[HUE] = { - { - .id = V4L2_CID_HUE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Hue", - .minimum = -90, - .maximum = 90, - .step = 1, - .default_value = 0, - }, - .set_control = sethue - }, -[SATURATION] = { - { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 64, - }, - .set_control = setsaturation - }, -[BRIGHTNESS] = { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 0, - }, - .set_control = setbrightness - }, -[CONTRAST] = { - { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 32, - }, - .set_control = setcontrast - }, -[GAIN] = { - { - .id = V4L2_CID_GAIN, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Main Gain", - .minimum = 0, - .maximum = 63, - .step = 1, - .default_value = 20, - }, - .set_control = setgain - }, -[EXPOSURE] = { - { - .id = V4L2_CID_EXPOSURE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Exposure", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 120, - }, - .set_control = setexposure - }, -[AGC] = { - { - .id = V4L2_CID_AUTOGAIN, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Auto Gain", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - .set_control = setagc - }, -[AWB] = { - { - .id = V4L2_CID_AUTO_WHITE_BALANCE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Auto White Balance", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - .set_control = setawb - }, -[AEC] = { - { - .id = V4L2_CID_EXPOSURE_AUTO, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Auto Exposure", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - }, - .set_control = setaec - }, -[SHARPNESS] = { - { - .id = V4L2_CID_SHARPNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Sharpness", - .minimum = 0, - .maximum = 63, - .step = 1, - .default_value = 0, - }, - .set_control = setsharpness - }, -[HFLIP] = { - { - .id = V4L2_CID_HFLIP, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "HFlip", - .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 - }, -[LIGHTFREQ] = { - { - .id = V4L2_CID_POWER_LINE_FREQUENCY, - .type = V4L2_CTRL_TYPE_MENU, - .name = "Light Frequency Filter", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 0, - }, - .set_control = setlightfreq - }, -}; static const struct v4l2_pix_format ov772x_mode[] = { {320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, @@ -972,12 +800,10 @@ static void set_frame_rate(struct gspca_dev *gspca_dev) PDEBUG(D_PROBE, "frame_rate: %d", r->fps); } -static void sethue(struct gspca_dev *gspca_dev) +static void sethue(struct gspca_dev *gspca_dev, s32 val) { struct sd *sd = (struct sd *) gspca_dev; - int val; - val = sd->ctrls[HUE].val; if (sd->sensor == SENSOR_OV767x) { /* TBD */ } else { @@ -1014,12 +840,10 @@ static void sethue(struct gspca_dev *gspca_dev) } } -static void setsaturation(struct gspca_dev *gspca_dev) +static void setsaturation(struct gspca_dev *gspca_dev, s32 val) { struct sd *sd = (struct sd *) gspca_dev; - int val; - val = sd->ctrls[SATURATION].val; if (sd->sensor == SENSOR_OV767x) { int i; static u8 color_tb[][6] = { @@ -1040,12 +864,10 @@ static void setsaturation(struct gspca_dev *gspca_dev) } } -static void setbrightness(struct gspca_dev *gspca_dev) +static void setbrightness(struct gspca_dev *gspca_dev, s32 val) { struct sd *sd = (struct sd *) gspca_dev; - int val; - val = sd->ctrls[BRIGHTNESS].val; if (sd->sensor == SENSOR_OV767x) { if (val < 0) val = 0x80 - val; @@ -1055,27 +877,18 @@ static void setbrightness(struct gspca_dev *gspca_dev) } } -static void setcontrast(struct gspca_dev *gspca_dev) +static void setcontrast(struct gspca_dev *gspca_dev, s32 val) { struct sd *sd = (struct sd *) gspca_dev; - u8 val; - val = sd->ctrls[CONTRAST].val; if (sd->sensor == SENSOR_OV767x) sccb_reg_write(gspca_dev, 0x56, val); /* contras */ else sccb_reg_write(gspca_dev, 0x9c, val); } -static void setgain(struct gspca_dev *gspca_dev) +static void setgain(struct gspca_dev *gspca_dev, s32 val) { - struct sd *sd = (struct sd *) gspca_dev; - u8 val; - - if (sd->ctrls[AGC].val) - return; - - val = sd->ctrls[GAIN].val; switch (val & 0x30) { case 0x00: val &= 0x0f; @@ -1097,15 +910,15 @@ static void setgain(struct gspca_dev *gspca_dev) sccb_reg_write(gspca_dev, 0x00, val); } -static void setexposure(struct gspca_dev *gspca_dev) +static s32 getgain(struct gspca_dev *gspca_dev) { - struct sd *sd = (struct sd *) gspca_dev; - u8 val; + return sccb_reg_read(gspca_dev, 0x00); +} - if (sd->ctrls[AEC].val) - return; +static void setexposure(struct gspca_dev *gspca_dev, s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; - val = sd->ctrls[EXPOSURE].val; if (sd->sensor == SENSOR_OV767x) { /* set only aec[9:2] */ @@ -1123,11 +936,23 @@ static void setexposure(struct gspca_dev *gspca_dev) } } -static void setagc(struct gspca_dev *gspca_dev) +static s32 getexposure(struct gspca_dev *gspca_dev) { struct sd *sd = (struct sd *) gspca_dev; - if (sd->ctrls[AGC].val) { + if (sd->sensor == SENSOR_OV767x) { + /* get only aec[9:2] */ + return sccb_reg_read(gspca_dev, 0x10); /* aech */ + } else { + u8 hi = sccb_reg_read(gspca_dev, 0x08); + u8 lo = sccb_reg_read(gspca_dev, 0x10); + return (hi << 8 | lo) >> 1; + } +} + +static void setagc(struct gspca_dev *gspca_dev, s32 val) +{ + if (val) { sccb_reg_write(gspca_dev, 0x13, sccb_reg_read(gspca_dev, 0x13) | 0x04); sccb_reg_write(gspca_dev, 0x64, @@ -1137,16 +962,14 @@ static void setagc(struct gspca_dev *gspca_dev) sccb_reg_read(gspca_dev, 0x13) & ~0x04); sccb_reg_write(gspca_dev, 0x64, sccb_reg_read(gspca_dev, 0x64) & ~0x03); - - setgain(gspca_dev); } } -static void setawb(struct gspca_dev *gspca_dev) +static void setawb(struct gspca_dev *gspca_dev, s32 val) { struct sd *sd = (struct sd *) gspca_dev; - if (sd->ctrls[AWB].val) { + if (val) { sccb_reg_write(gspca_dev, 0x13, sccb_reg_read(gspca_dev, 0x13) | 0x02); if (sd->sensor == SENSOR_OV772x) @@ -1161,7 +984,7 @@ static void setawb(struct gspca_dev *gspca_dev) } } -static void setaec(struct gspca_dev *gspca_dev) +static void setaec(struct gspca_dev *gspca_dev, s32 val) { struct sd *sd = (struct sd *) gspca_dev; u8 data; @@ -1169,31 +992,25 @@ static void setaec(struct gspca_dev *gspca_dev) data = sd->sensor == SENSOR_OV767x ? 0x05 : /* agc + aec */ 0x01; /* agc */ - if (sd->ctrls[AEC].val) + switch (val) { + case V4L2_EXPOSURE_AUTO: sccb_reg_write(gspca_dev, 0x13, sccb_reg_read(gspca_dev, 0x13) | data); - else { + break; + case V4L2_EXPOSURE_MANUAL: sccb_reg_write(gspca_dev, 0x13, sccb_reg_read(gspca_dev, 0x13) & ~data); - if (sd->sensor == SENSOR_OV767x) - sd->ctrls[EXPOSURE].val = - sccb_reg_read(gspca_dev, 10); /* aech */ - else - setexposure(gspca_dev); + break; } } -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; - u8 val; - - val = sd->ctrls[SHARPNESS].val; sccb_reg_write(gspca_dev, 0x91, val); /* Auto de-noise threshold */ sccb_reg_write(gspca_dev, 0x8e, val); /* De-noise threshold */ } -static void sethvflip(struct gspca_dev *gspca_dev) +static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip) { struct sd *sd = (struct sd *) gspca_dev; u8 val; @@ -1201,28 +1018,27 @@ static void sethvflip(struct gspca_dev *gspca_dev) if (sd->sensor == SENSOR_OV767x) { val = sccb_reg_read(gspca_dev, 0x1e); /* mvfp */ val &= ~0x30; - if (sd->ctrls[HFLIP].val) + if (hflip) val |= 0x20; - if (sd->ctrls[VFLIP].val) + if (vflip) val |= 0x10; sccb_reg_write(gspca_dev, 0x1e, val); } else { val = sccb_reg_read(gspca_dev, 0x0c); val &= ~0xc0; - if (sd->ctrls[HFLIP].val == 0) + if (hflip == 0) val |= 0x40; - if (sd->ctrls[VFLIP].val == 0) + if (vflip == 0) val |= 0x80; sccb_reg_write(gspca_dev, 0x0c, val); } } -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; - u8 val; - val = sd->ctrls[LIGHTFREQ].val ? 0x9e : 0x00; + val = val ? 0x9e : 0x00; if (sd->sensor == SENSOR_OV767x) { sccb_reg_write(gspca_dev, 0x2a, 0x00); if (val) @@ -1241,8 +1057,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam = &gspca_dev->cam; - cam->ctrls = sd->ctrls; - cam->cam_mode = ov772x_mode; cam->nmodes = ARRAY_SIZE(ov772x_mode); @@ -1251,6 +1065,195 @@ static int sd_config(struct gspca_dev *gspca_dev, return 0; } +static int ov534_g_volatile_ctrl(struct v4l2_ctrl *ctrl) +{ + 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->gain && gspca_dev->streaming) + sd->gain->val = getgain(gspca_dev); + return gspca_dev->usb_err; + + case V4L2_CID_EXPOSURE_AUTO: + gspca_dev->usb_err = 0; + if (ctrl->val == V4L2_EXPOSURE_AUTO && sd->exposure && + gspca_dev->streaming) + sd->exposure->val = getexposure(gspca_dev); + return gspca_dev->usb_err; + } + return -EINVAL; +} + +static int ov534_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; + + gspca_dev->usb_err = 0; + if (!gspca_dev->streaming) + return 0; + + switch (ctrl->id) { + case V4L2_CID_HUE: + sethue(gspca_dev, ctrl->val); + break; + case V4L2_CID_SATURATION: + setsaturation(gspca_dev, ctrl->val); + break; + case V4L2_CID_BRIGHTNESS: + setbrightness(gspca_dev, ctrl->val); + break; + case V4L2_CID_CONTRAST: + setcontrast(gspca_dev, ctrl->val); + break; + case V4L2_CID_AUTOGAIN: + /* case V4L2_CID_GAIN: */ + setagc(gspca_dev, ctrl->val); + if (!gspca_dev->usb_err && !ctrl->val && sd->gain) + setgain(gspca_dev, sd->gain->val); + break; + case V4L2_CID_AUTO_WHITE_BALANCE: + setawb(gspca_dev, ctrl->val); + break; + case V4L2_CID_EXPOSURE_AUTO: + /* case V4L2_CID_EXPOSURE: */ + setaec(gspca_dev, ctrl->val); + if (!gspca_dev->usb_err && ctrl->val == V4L2_EXPOSURE_MANUAL && + sd->exposure) + setexposure(gspca_dev, sd->exposure->val); + break; + case V4L2_CID_SHARPNESS: + setsharpness(gspca_dev, ctrl->val); + break; + case V4L2_CID_HFLIP: + sethvflip(gspca_dev, ctrl->val, sd->vflip->val); + break; + case V4L2_CID_VFLIP: + sethvflip(gspca_dev, sd->hflip->val, ctrl->val); + break; + case V4L2_CID_POWER_LINE_FREQUENCY: + setlightfreq(gspca_dev, ctrl->val); + break; + } + return gspca_dev->usb_err; +} + +static const struct v4l2_ctrl_ops ov534_ctrl_ops = { + .g_volatile_ctrl = ov534_g_volatile_ctrl, + .s_ctrl = ov534_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; + /* parameters with different values between the supported sensors */ + int saturation_min; + int saturation_max; + int saturation_def; + int brightness_min; + int brightness_max; + int brightness_def; + int contrast_max; + int contrast_def; + int exposure_min; + int exposure_max; + int exposure_def; + int hflip_def; + + if (sd->sensor == SENSOR_OV767x) { + saturation_min = 0, + saturation_max = 6, + saturation_def = 3, + brightness_min = -127; + brightness_max = 127; + brightness_def = 0; + contrast_max = 0x80; + contrast_def = 0x40; + exposure_min = 0x08; + exposure_max = 0x60; + exposure_def = 0x13; + hflip_def = 1; + } else { + saturation_min = 0, + saturation_max = 255, + saturation_def = 64, + brightness_min = 0; + brightness_max = 255; + brightness_def = 0; + contrast_max = 255; + contrast_def = 32; + exposure_min = 0; + exposure_max = 255; + exposure_def = 120; + hflip_def = 0; + } + + gspca_dev->vdev.ctrl_handler = hdl; + + v4l2_ctrl_handler_init(hdl, 13); + + if (sd->sensor == SENSOR_OV772x) + sd->hue = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, + V4L2_CID_HUE, -90, 90, 1, 0); + + sd->saturation = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, + V4L2_CID_SATURATION, saturation_min, saturation_max, 1, + saturation_def); + sd->brightness = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, + V4L2_CID_BRIGHTNESS, brightness_min, brightness_max, 1, + brightness_def); + sd->contrast = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, + V4L2_CID_CONTRAST, 0, contrast_max, 1, contrast_def); + + if (sd->sensor == SENSOR_OV772x) { + sd->autogain = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, + V4L2_CID_AUTOGAIN, 0, 1, 1, 1); + sd->gain = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, + V4L2_CID_GAIN, 0, 63, 1, 20); + } + + sd->autoexposure = v4l2_ctrl_new_std_menu(hdl, &ov534_ctrl_ops, + V4L2_CID_EXPOSURE_AUTO, + V4L2_EXPOSURE_MANUAL, 0, + V4L2_EXPOSURE_AUTO); + sd->exposure = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, + V4L2_CID_EXPOSURE, exposure_min, exposure_max, 1, + exposure_def); + + sd->autowhitebalance = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, + V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1); + + if (sd->sensor == SENSOR_OV772x) + sd->sharpness = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, + V4L2_CID_SHARPNESS, 0, 63, 1, 0); + + sd->hflip = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, + V4L2_CID_HFLIP, 0, 1, 1, hflip_def); + sd->vflip = v4l2_ctrl_new_std(hdl, &ov534_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); + sd->plfreq = v4l2_ctrl_new_std_menu(hdl, &ov534_ctrl_ops, + V4L2_CID_POWER_LINE_FREQUENCY, + V4L2_CID_POWER_LINE_FREQUENCY_50HZ, 0, + V4L2_CID_POWER_LINE_FREQUENCY_DISABLED); + + if (hdl->error) { + pr_err("Could not initialize controls\n"); + return hdl->error; + } + + if (sd->sensor == SENSOR_OV772x) + v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, true); + + v4l2_ctrl_auto_cluster(2, &sd->autoexposure, V4L2_EXPOSURE_MANUAL, + true); + + return 0; +} + /* this function is called at probe and resume time */ static int sd_init(struct gspca_dev *gspca_dev) { @@ -1286,24 +1289,6 @@ static int sd_init(struct gspca_dev *gspca_dev) if ((sensor_id & 0xfff0) == 0x7670) { sd->sensor = SENSOR_OV767x; - gspca_dev->ctrl_dis = (1 << HUE) | - (1 << GAIN) | - (1 << AGC) | - (1 << SHARPNESS); /* auto */ - sd->ctrls[SATURATION].min = 0, - sd->ctrls[SATURATION].max = 6, - sd->ctrls[SATURATION].def = 3, - sd->ctrls[BRIGHTNESS].min = -127; - sd->ctrls[BRIGHTNESS].max = 127; - sd->ctrls[BRIGHTNESS].def = 0; - sd->ctrls[CONTRAST].max = 0x80; - sd->ctrls[CONTRAST].def = 0x40; - sd->ctrls[EXPOSURE].min = 0x08; - sd->ctrls[EXPOSURE].max = 0x60; - sd->ctrls[EXPOSURE].def = 0x13; - sd->ctrls[SHARPNESS].max = 9; - sd->ctrls[SHARPNESS].def = 4; - sd->ctrls[HFLIP].def = 1; gspca_dev->cam.cam_mode = ov767x_mode; gspca_dev->cam.nmodes = ARRAY_SIZE(ov767x_mode); } else { @@ -1366,22 +1351,23 @@ static int sd_start(struct gspca_dev *gspca_dev) set_frame_rate(gspca_dev); - if (!(gspca_dev->ctrl_dis & (1 << HUE))) - sethue(gspca_dev); - setsaturation(gspca_dev); - if (!(gspca_dev->ctrl_dis & (1 << AGC))) - setagc(gspca_dev); - setawb(gspca_dev); - setaec(gspca_dev); - if (!(gspca_dev->ctrl_dis & (1 << GAIN))) - setgain(gspca_dev); - setexposure(gspca_dev); - setbrightness(gspca_dev); - setcontrast(gspca_dev); - if (!(gspca_dev->ctrl_dis & (1 << SHARPNESS))) - setsharpness(gspca_dev); - sethvflip(gspca_dev); - setlightfreq(gspca_dev); + if (sd->hue) + sethue(gspca_dev, v4l2_ctrl_g_ctrl(sd->hue)); + setsaturation(gspca_dev, v4l2_ctrl_g_ctrl(sd->saturation)); + if (sd->autogain) + setagc(gspca_dev, v4l2_ctrl_g_ctrl(sd->autogain)); + setawb(gspca_dev, v4l2_ctrl_g_ctrl(sd->autowhitebalance)); + setaec(gspca_dev, v4l2_ctrl_g_ctrl(sd->autoexposure)); + if (sd->gain) + setgain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain)); + setexposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure)); + setbrightness(gspca_dev, v4l2_ctrl_g_ctrl(sd->brightness)); + setcontrast(gspca_dev, v4l2_ctrl_g_ctrl(sd->contrast)); + if (sd->sharpness) + setsharpness(gspca_dev, v4l2_ctrl_g_ctrl(sd->sharpness)); + sethvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip), + v4l2_ctrl_g_ctrl(sd->vflip)); + setlightfreq(gspca_dev, v4l2_ctrl_g_ctrl(sd->plfreq)); ov534_set_led(gspca_dev, 1); ov534_reg_write(gspca_dev, 0xe0, 0x00); @@ -1483,25 +1469,6 @@ scan_next: } while (remaining_len > 0); } -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, "Disabled"); - return 0; - case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */ - strcpy((char *) menu->name, "50 Hz"); - return 0; - } - break; - } - - return -EINVAL; -} - /* get stream parameters (framerate) */ static void sd_get_streamparm(struct gspca_dev *gspca_dev, struct v4l2_streamparm *parm) @@ -1536,14 +1503,12 @@ static void sd_set_streamparm(struct gspca_dev *gspca_dev, /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, - .ctrls = sd_ctrls, - .nctrls = ARRAY_SIZE(sd_ctrls), .config = sd_config, .init = sd_init, + .init_controls = sd_init_controls, .start = sd_start, .stopN = sd_stopN, .pkt_scan = sd_pkt_scan, - .querymenu = sd_querymenu, .get_streamparm = sd_get_streamparm, .set_streamparm = sd_set_streamparm, };