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

Commit e89fca92 authored by Antonio Ospite's avatar Antonio Ospite Committed by Mauro Carvalho Chehab
Browse files

[media] gspca - ov534: Add Hue control

parent c8e1fb4a
Loading
Loading
Loading
Loading
+63 −2
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@

#include "gspca.h"

#include <linux/fixp-arith.h>

#define OV534_REG_ADDRESS	0xf1	/* sensor address */
#define OV534_REG_SUBADDR	0xf2
#define OV534_REG_WRITE		0xf3
@@ -53,6 +55,7 @@ MODULE_LICENSE("GPL");

/* controls */
enum e_ctrl {
	HUE,
	SATURATION,
	BRIGHTNESS,
	CONTRAST,
@@ -87,6 +90,7 @@ enum sensors {
};

/* 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);
@@ -103,6 +107,18 @@ 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,
@@ -684,7 +700,7 @@ static const u8 sensor_init_772x[][2] = {
	{ 0x9c, 0x20 },
	{ 0x9e, 0x81 },

	{ 0xa6, 0x06 },
	{ 0xa6, 0x07 },
	{ 0x7e, 0x0c },
	{ 0x7f, 0x16 },
	{ 0x80, 0x2a },
@@ -955,6 +971,48 @@ 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)
{
	struct sd *sd = (struct sd *) gspca_dev;
	int val;

	val = sd->ctrls[HUE].val;
	if (sd->sensor == SENSOR_OV767x) {
		/* TBD */
	} else {
		s16 huesin;
		s16 huecos;

		/* fixp_sin and fixp_cos accept only positive values, while
		 * our val is between -90 and 90
		 */
		val += 360;

		/* According to the datasheet the registers expect HUESIN and
		 * HUECOS to be the result of the trigonometric functions,
		 * scaled by 0x80.
		 *
		 * The 0x100 here represents the maximun absolute value
		 * returned byt fixp_sin and fixp_cos, so the scaling will
		 * consider the result like in the interval [-1.0, 1.0].
		 */
		huesin = fixp_sin(val) * 0x80 / 0x100;
		huecos = fixp_cos(val) * 0x80 / 0x100;

		if (huesin < 0) {
			sccb_reg_write(gspca_dev, 0xab,
				sccb_reg_read(gspca_dev, 0xab) | 0x2);
			huesin = -huesin;
		} else {
			sccb_reg_write(gspca_dev, 0xab,
				sccb_reg_read(gspca_dev, 0xab) & ~0x2);

		}
		sccb_reg_write(gspca_dev, 0xa9, (u8)huecos);
		sccb_reg_write(gspca_dev, 0xaa, (u8)huesin);
	}
}

static void setsaturation(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *) gspca_dev;
@@ -1231,7 +1289,8 @@ static int sd_init(struct gspca_dev *gspca_dev)

	if ((sensor_id & 0xfff0) == 0x7670) {
		sd->sensor = SENSOR_OV767x;
		gspca_dev->ctrl_dis = (1 << GAIN) |
		gspca_dev->ctrl_dis = (1 << HUE) |
					(1 << GAIN) |
					(1 << AGC) |
					(1 << SHARPNESS);	/* auto */
		sd->ctrls[SATURATION].min = 0,
@@ -1310,6 +1369,8 @@ 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);