V4L/DVB (12620): gspca_mr97310a: cleanup/fixup control handling

gspca_mr97310a: cleanup/fixup control handling

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index db2f84e..3bdf064 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -64,11 +64,9 @@
 	u8 cam_type;	/* 0 is CIF and 1 is VGA */
 	u8 sensor_type;	/* We use 0 and 1 here, too. */
 	u8 do_lcd_stop;
-	u8 regs[15];
 
 	int brightness;
 	u16 exposure;
-	u8 autogain;
 	u8 gain;
 };
 
@@ -85,10 +83,14 @@
 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
+static void setbrightness(struct gspca_dev *gspca_dev);
+static void setexposure(struct gspca_dev *gspca_dev);
+static void setgain(struct gspca_dev *gspca_dev);
 
 /* V4L2 controls supported by the driver */
 static struct ctrl sd_ctrls[] = {
 	{
+#define BRIGHTNESS_IDX 0
 		{
 			.id = V4L2_CID_BRIGHTNESS,
 			.type = V4L2_CTRL_TYPE_INTEGER,
@@ -103,6 +105,7 @@
 		.get = sd_getbrightness,
 	},
 	{
+#define EXPOSURE_IDX 1
 		{
 			.id = V4L2_CID_EXPOSURE,
 			.type = V4L2_CTRL_TYPE_INTEGER,
@@ -117,6 +120,7 @@
 		.get = sd_getexposure,
 	},
 	{
+#define GAIN_IDX 2
 		{
 			.id = V4L2_CID_GAIN,
 			.type = V4L2_CTRL_TYPE_INTEGER,
@@ -360,14 +364,24 @@
 	cam = &gspca_dev->cam;
 	cam->cam_mode = vga_mode;
 	cam->nmodes = ARRAY_SIZE(vga_mode);
-	sd->cam_type = CAM_TYPE_VGA;
+
 	PDEBUG(D_PROBE,
 		"MR97310A camera detected"
 		" (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+
 	if (id->idProduct == 0x010e) {
-		cam->nmodes--;
 		sd->cam_type = CAM_TYPE_CIF;
+		cam->nmodes--;
+	} else {
+		sd->cam_type = CAM_TYPE_VGA;
+		gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) |
+				      (1 << EXPOSURE_IDX) | (1 << GAIN_IDX);
 	}
+
+	sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
+	sd->exposure = MR97310A_EXPOSURE_DEFAULT;
+	sd->gain = MR97310A_GAIN_DEFAULT;
+
 	return 0;
 }
 
@@ -377,35 +391,6 @@
 	return 0;
 }
 
-static int adjust_cif_sensor(struct gspca_dev *gspca_dev)
-{
-	/*
-	 * FIXME: The following sequence resets brightness, contrast, and
-	 * related  settings. Some of the values are adjustable, presumably
-	 * based upon what is detected in the frames. Here, only some
-	 * vaules are used which are compromises. When more is known about
-	 * what is done here, this needs to be moved out to presently
-	 * nonexistent functions which do controls. The same control messages
-	 * do work for all of the CIF cameras.
-	 */
-
-	const struct sensor_w_data  cif_sensor1_adjust_data[] = {
-		{0x02, 0x01, {0x10, 0x12, 0x0a}, 3},
-		/* Last or possibly two last bytes adjustable, above. */
-		{0x13, 0x04, {0x01}, 1}, /* seems to mean "write" */
-		{0x05, 0x01, {0x22, 0x00, 0x81, 0x06}, 4},
-		/* Last or possibly two last bytes adjustable, above. */
-		{0x13, 0x04, {0x01}, 1},
-		{0x09, 0x02, {0x05, 0x00, 0x00, 0x05, 0x07, 0x16}, 6},
-		/* Last or possibly two last bytes adjustable, above. */
-		{0x13, 0x04, {0x01}, 1},
-		{0, 0, {0}, 0}
-	};
-
-	return sensor_write_regs(gspca_dev, cif_sensor1_adjust_data,
-				 ARRAY_SIZE(cif_sensor1_adjust_data));
-}
-
 static int start_cif_cam(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
@@ -452,6 +437,11 @@
 		sd->sensor_type = 1;
 
 	PDEBUG(D_ERR, "Sensor type is %01x", sd->sensor_type);
+
+	if (sd->sensor_type == 0)
+		gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) |
+				      (1 << EXPOSURE_IDX) | (1 << GAIN_IDX);
+
 	memcpy(data, startup_string, 11);
 	if (sd->sensor_type)
 		data[5] = 0xbb;
@@ -504,18 +494,15 @@
 					 ARRAY_SIZE(cif_sensor0_init_data));
 	} else {	/* sd->sensor_type = 1 */
 		const struct sensor_w_data cif_sensor1_init_data[] = {
+			/* Reg 3,4, 7,8 get set by the controls */
 			{0x02, 0x00, {0x10}, 1},
-			{0x03, 0x01, {0x12}, 1},
-			{0x04, 0x01, {0x05}, 1},
-			{0x05, 0x01, {0x65}, 1},
-			{0x06, 0x01, {0x32}, 1},
-			{0x07, 0x01, {0x00}, 1},
-			{0x08, 0x02, {0x06}, 1},
+			{0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */
+			{0x06, 0x01, {0x00}, 1},
 			{0x09, 0x02, {0x0e}, 1},
 			{0x0a, 0x02, {0x05}, 1},
 			{0x0b, 0x02, {0x05}, 1},
 			{0x0c, 0x02, {0x0f}, 1},
-			{0x0d, 0x02, {0x00}, 1},
+			{0x0d, 0x02, {0x07}, 1},
 			{0x0e, 0x02, {0x0c}, 1},
 			{0x0f, 0x00, {0x00}, 1},
 			{0x10, 0x00, {0x06}, 1},
@@ -530,19 +517,18 @@
 	if (err_code < 0)
 		return err_code;
 
+	setbrightness(gspca_dev);
+	setexposure(gspca_dev);
+	setgain(gspca_dev);
+
 	msleep(200);
+
 	data[0] = 0x00;
 	data[1] = 0x4d;  /* ISOC transfering enable... */
 	err_code = mr_write(gspca_dev, 2);
 	if (err_code < 0)
 		return err_code;
 
-	msleep(200);
-	err_code = adjust_cif_sensor(gspca_dev);
-	if (err_code < 0)
-		return err_code;
-
-	msleep(200);
 	return 0;
 }
 
@@ -711,11 +697,6 @@
 	int err_code;
 	struct cam *cam;
 
-	/* TEST TEST */
-	int i;
-	for (i = 2; i <= 14; i++)
-		sd->regs[i] = sd_ctrls[i - 2].qctrl.default_value;
-
 	cam = &gspca_dev->cam;
 	sd->sof_read = 0;
 	/*
@@ -760,11 +741,16 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	u8 val;
+
+	if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX))
+		return;
+
+	/* Note register 7 is also seen as 0x8x or 0xCx in dumps */
 	if (sd->brightness > 0) {
-		sensor_write1(gspca_dev, 7, 0);
+		sensor_write1(gspca_dev, 7, 0x00);
 		val = sd->brightness;
 	} else {
-		sensor_write1(gspca_dev, 7, 1);
+		sensor_write1(gspca_dev, 7, 0x01);
 		val = 257 - sd->brightness;
 	}
 	sensor_write1(gspca_dev, 8, val);
@@ -775,6 +761,9 @@
 	struct sd *sd = (struct sd *) gspca_dev;
 	u8 val;
 
+	if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
+		return;
+
 	val = sd->exposure >> 4;
 	sensor_write1(gspca_dev, 3, val);
 	val = sd->exposure & 0xf;
@@ -785,6 +774,9 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
+	if (gspca_dev->ctrl_dis & (1 << GAIN_IDX))
+		return;
+
 	sensor_write1(gspca_dev, 3, sd->gain);
 }