Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 62833acd authored by Jean-François Moine's avatar Jean-François Moine Committed by Mauro Carvalho Chehab
Browse files

[media] gspca - ov519: Use the new video control mechanism

parent 016f2362
Loading
Loading
Loading
Loading
+75 −241
Original line number Diff line number Diff line
@@ -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,136 +4338,16 @@ static void setfreq(struct sd *sd)
		}
	}
}

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)
{
	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)
static void setfreq(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *) gspca_dev;

	*val = sd->autobrightness;
	return 0;
}
	setfreq_i(sd);

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;
}

static int sd_querymenu(struct gspca_dev *gspca_dev,
			struct v4l2_querymenu *menu)
+1 −1
Original line number Diff line number Diff line
@@ -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 {