diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 17b0d51d91e5..2417a7e70a42 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -57,10 +57,24 @@ static int frame_rate;
  * 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;
@@ -82,13 +96,6 @@ struct sd {
 	/* 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
@@ -130,29 +137,16 @@ struct sd {
 #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,
@@ -160,14 +154,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 CONTRAST_IDX 1
-	{
+[CONTRAST] = {
 	    {
 		.id      = V4L2_CID_CONTRAST,
 		.type    = V4L2_CTRL_TYPE_INTEGER,
@@ -175,14 +166,11 @@ static const struct ctrl sd_ctrls[] = {
 		.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,
@@ -190,15 +178,12 @@ static const struct ctrl sd_ctrls[] = {
 		.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,
@@ -206,14 +191,11 @@ static const struct ctrl sd_ctrls[] = {
 		.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,
@@ -221,14 +203,11 @@ static const struct ctrl sd_ctrls[] = {
 		.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,
@@ -236,14 +215,11 @@ static const struct ctrl sd_ctrls[] = {
 		.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,
@@ -251,26 +227,9 @@ static const struct ctrl sd_ctrls[] = {
 		.minimum = 0,
 		.maximum = 2,	/* 0: 0, 1: 50Hz, 2:60Hz */
 		.step    = 1,
-#define FREQ_DEF 0
-		.default_value = FREQ_DEF,
+		.default_value = 0,
 	    },
-	    .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,
-	    },
-	    .set = sd_setfreq,
-	    .get = sd_getfreq,
+	    .set_control = setfreq,
 	},
 };
 
@@ -3139,36 +3098,23 @@ static int sd_config(struct gspca_dev *gspca_dev,
 			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:
@@ -3203,6 +3149,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
 		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;
@@ -3225,6 +3173,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
 			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;
@@ -3795,15 +3745,17 @@ static int mode_init_ov_sensor_regs(struct sd *sd)
 	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);
@@ -3954,9 +3906,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
 	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 */
@@ -4211,7 +4163,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
 	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:
@@ -4226,7 +4178,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
 	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:
@@ -4242,7 +4194,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
 	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:
@@ -4284,7 +4236,7 @@ static void setcolors(struct gspca_dev *gspca_dev)
 	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:
@@ -4314,23 +4266,25 @@ static void setcolors(struct gspca_dev *gspca_dev)
 	}
 }
 
-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;
@@ -4352,7 +4306,7 @@ static void setfreq(struct sd *sd)
 			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);
@@ -4384,135 +4338,15 @@ static void setfreq(struct sd *sd)
 		}
 	}
 }
-
-static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+static void setfreq(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	sd->brightness = val;
-	if (gspca_dev->streaming)
-		setbrightness(gspca_dev);
-	return 0;
-}
+	setfreq_i(sd);
 
-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)
-{
-	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;
-
-	*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,
diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c
index 1c6c89419577..d070c7ffbfa9 100644
--- a/drivers/media/video/gspca/w996Xcf.c
+++ b/drivers/media/video/gspca/w996Xcf.c
@@ -437,7 +437,7 @@ static int w9968cf_set_crop_window(struct sd *sd)
 	if (sd->sensor == SEN_OV7620) {
 		/* Sigh, this is dependend on the clock / framerate changes
 		   made by the frequency control, sick. */
-		if (sd->freq == 1) {
+		if (sd->ctrls[FREQ].val == 1) {
 			start_cropx = 277;
 			start_cropy = 37;
 		} else {