Эх сурвалжийг харах

V4L/DVB (11871): gspca - spca561: Change the Rev12a controls.

- Extend the gain range
- Adjust the exposure
- Remove the broken autogain

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Hans de Goede 16 жил өмнө
parent
commit
d0848eb286

+ 32 - 45
drivers/media/video/gspca/spca561.c

@@ -34,8 +34,8 @@ struct sd {
 
 	__u16 exposure;			/* rev12a only */
 #define EXPOSURE_MIN 1
-#define EXPOSURE_DEF 200
-#define EXPOSURE_MAX (4095 - 900) /* see set_exposure */
+#define EXPOSURE_DEF 700		/* == 10 fps */
+#define EXPOSURE_MAX (2047 + 325)	/* see setexposure */
 
 	__u8 contrast;			/* rev72a only */
 #define CONTRAST_MIN 0x00
@@ -58,9 +58,9 @@ struct sd {
 #define AUTOGAIN_MAX 1
 
 	__u8 gain;			/* rev12a only */
-#define GAIN_MIN 0x0
-#define GAIN_DEF 0x24
-#define GAIN_MAX 0x24
+#define GAIN_MIN 0
+#define GAIN_DEF 63
+#define GAIN_MAX 255
 
 #define EXPO12A_DEF 3
 	__u8 expo12a;		/* expo/gain? for rev 12a */
@@ -549,8 +549,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
 static void setexposure(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int expo;
-	int clock_divider;
+	int i, expo = 0;
 
 	/* Register 0x8309 controls exposure for the spca561,
 	   the basic exposure setting goes from 1-2047, where 1 is completely
@@ -564,16 +563,22 @@ static void setexposure(struct gspca_dev *gspca_dev)
 	   configure a divider for the base framerate which us used at the
 	   exposure setting of 1-300. These bits configure the base framerate
 	   according to the following formula: fps = 60 / (value + 2) */
-	if (sd->exposure < 2048) {
-		expo = sd->exposure;
-		clock_divider = 0;
-	} else {
-		/* Add 900 to make the 0 setting of the second part of the
-		   exposure equal to the 2047 setting of the first part. */
-		expo = (sd->exposure - 2048) + 900;
-		clock_divider = 3;
+
+	/* We choose to use the high bits setting the fixed framerate divisor
+	   asap, as setting high basic exposure setting without the fixed
+	   divider in combination with high gains makes the cam stop */
+	int table[] =  { 0, 450, 550, 625, EXPOSURE_MAX };
+
+	for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
+		if (sd->exposure <= table[i + 1]) {
+			expo  = sd->exposure - table[i];
+			if (i)
+				expo += 300;
+			expo |= i << 11;
+			break;
+		}
 	}
-	expo |= clock_divider << 11;
+
 	gspca_dev->usb_buf[0] = expo;
 	gspca_dev->usb_buf[1] = expo >> 8;
 	reg_w_buf(gspca_dev, 0x8309, 2);
@@ -584,7 +589,16 @@ static void setgain(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	gspca_dev->usb_buf[0] = sd->gain;
+	/* gain reg low 6 bits  0-63 gain, bit 6 and 7, both double the
+	   sensitivity when set, so 31 + one of them set == 63, and 15
+	   with both of them set == 63 */
+	if (sd->gain < 64)
+		gspca_dev->usb_buf[0] = sd->gain;
+	else if (sd->gain < 128)
+		gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40;
+	else
+		gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xC0;
+
 	gspca_dev->usb_buf[1] = 0;
 	reg_w_buf(gspca_dev, 0x8335, 2);
 }
@@ -629,8 +643,7 @@ static int sd_start_12a(struct gspca_dev *gspca_dev)
 	reg_w_buf(gspca_dev, 0x8391, 8);
 	reg_w_buf(gspca_dev, 0x8390, 8);
 	setwhite(gspca_dev);
-	setautogain(gspca_dev);
-/*	setgain(gspca_dev);		*/
+	setgain(gspca_dev);
 	setexposure(gspca_dev);
 	return 0;
 }
@@ -762,18 +775,6 @@ static void do_autogain(struct gspca_dev *gspca_dev)
 			i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
 		}
 		break;
-	case Rev012A:
-		reg_r(gspca_dev, 0x8330, 2);
-		if (gspca_dev->usb_buf[1] > 0x08) {
-			gspca_dev->usb_buf[0] = ++sd->expo12a;
-			gspca_dev->usb_buf[1] = 0;
-			reg_w_buf(gspca_dev, 0x8339, 2);
-		} else if (gspca_dev->usb_buf[1] < 0x02) {
-			gspca_dev->usb_buf[0] = --sd->expo12a;
-			gspca_dev->usb_buf[1] = 0;
-			reg_w_buf(gspca_dev, 0x8339, 2);
-		}
-		break;
 	}
 }
 
@@ -952,19 +953,6 @@ static struct ctrl sd_ctrls_12a[] = {
 	    .set = sd_setexposure,
 	    .get = sd_getexposure,
 	},
-	{
-	    {
-		.id = V4L2_CID_AUTOGAIN,
-		.type = V4L2_CTRL_TYPE_BOOLEAN,
-		.name = "Auto Gain",
-		.minimum = AUTOGAIN_MIN,
-		.maximum = AUTOGAIN_MAX,
-		.step = 1,
-		.default_value = AUTOGAIN_DEF,
-	    },
-	    .set = sd_setautogain,
-	    .get = sd_getautogain,
-	},
 	{
 	    {
 		.id = V4L2_CID_GAIN,
@@ -1046,7 +1034,6 @@ static const struct sd_desc sd_desc_12a = {
 	.stopN = sd_stopN,
 	.stop0 = sd_stop0,
 	.pkt_scan = sd_pkt_scan,
-/*	.dq_callback = do_autogain,	 * fixme */
 };
 static const struct sd_desc sd_desc_72a = {
 	.name = MODULE_NAME,