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

Commit 0fc23d20 authored by Hans de Goede's avatar Hans de Goede Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (8873): gspca: Bad image offset with rev012a of spca561 and adjust exposure.



-Make raw bayer header size change from 20 to 16 affect rev072a only, my 2
 rev012a cams both have a header size of 20
-While testing this I also tested the new exposure setting (good work on
 finding the register JF), and after quite a bit of testing have found out the
 exact meaning of the register, this patch modifies setexposure to control
 the exposure over a much wider range.

Signed-off-by: default avatarHans de Goede <j.w.r.degoede@hhs.nl>
Signed-off-by: default avatarJean-Francois Moine <moinejf@free.fr>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent b77c0046
Loading
Loading
Loading
Loading
+36 −19
Original line number Diff line number Diff line
@@ -38,9 +38,9 @@ struct sd {
#define CONTRAST_MAX 0x3fff

	__u16 exposure;			/* rev12a only */
#define EXPOSURE_MIN 0
#define EXPOSURE_MIN 1
#define EXPOSURE_DEF 200
#define EXPOSURE_MAX 762
#define EXPOSURE_MAX (4095 - 900) /* see set_exposure */

	__u8 brightness;		/* rev72a only */
#define BRIGHTNESS_MIN 0
@@ -648,9 +648,31 @@ static void setexposure(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *) gspca_dev;
	int expo;
	int clock_divider;
	__u8 data[2];

	expo = sd->exposure + 0x20a8;	/* from test */
	/* Register 0x8309 controls exposure for the spca561,
	   the basic exposure setting goes from 1-2047, where 1 is completely
	   dark and 2047 is very bright. It not only influences exposure but
	   also the framerate (to allow for longer exposure) from 1 - 300 it
	   only raises the exposure time then from 300 - 600 it halves the
	   framerate to be able to further raise the exposure time and for every
	   300 more it halves the framerate again. This allows for a maximum
	   exposure time of circa 0.2 - 0.25 seconds (30 / (2000/3000) fps).
	   Sometimes this is not enough, the 1-2047 uses bits 0-10, bits 11-12
	   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;
	}
	expo |= clock_divider << 11;
	data[0] = expo;
	data[1] = expo >> 8;
	reg_w_buf(gspca_dev, 0x8309, data, 2);
@@ -680,23 +702,11 @@ static void setautogain(struct gspca_dev *gspca_dev)
static void sd_start_12a(struct gspca_dev *gspca_dev)
{
	struct usb_device *dev = gspca_dev->dev;
	int Clck;
	int Clck = 0x8a; /* lower 0x8X values lead to fps > 30 */
	__u8 Reg8307[] = { 0xaa, 0x00 };
	int mode;

	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
	switch (mode) {
	case 0:
	case 1:
		Clck = 0x8a;
		break;
	case 2:
		Clck = 0x85;
		break;
	default:
		Clck = 0x83;
		break;
	}
	if (mode <= 1) {
		/* Use compression on 320x240 and above */
		reg_w_val(dev, 0x8500, 0x10 | mode);
@@ -714,6 +724,7 @@ static void sd_start_12a(struct gspca_dev *gspca_dev)
	setcontrast(gspca_dev);
	setwhite(gspca_dev);
	setautogain(gspca_dev);
	setexposure(gspca_dev);
}
static void sd_start_72a(struct gspca_dev *gspca_dev)
{
@@ -849,6 +860,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
			__u8 *data,		/* isoc packet */
			int len)		/* iso packet length */
{
	struct sd *sd = (struct sd *) gspca_dev;

	switch (data[0]) {
	case 0:		/* start of frame */
		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
@@ -861,9 +874,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
					frame, data, len);
		} else {
			/* raw bayer (with a header, which we skip) */
/*fixme: is this specific to the rev012a? */
			if (sd->chip_revision == Rev012A) {
				data += 20;
				len -= 20;
			} else {
				data += 16;
				len -= 16;
			}
			gspca_frame_add(gspca_dev, FIRST_PACKET,
						frame, data, len);
		}