/*
 * Mars MR97310A library
 *
 * The original mr97310a driver, which supported the Aiptek Pencam VGA+, is
 * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com>
 *
 * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+
 * and for the routines for detecting and classifying these various cameras,
 * is Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
 *
 * Support for the control settings for the CIF cameras is
 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> and
 * Thomas Kaiser <thomas@kaiser-linux.li>
 *
 * Support for the control settings for the VGA cameras is
 * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
 *
 * Several previously unsupported cameras are owned and have been tested by
 * Hans de Goede <hdegoede@redhat.com> and
 * Thomas Kaiser <thomas@kaiser-linux.li> and
 * Theodore Kilgore <kilgota@auburn.edu> and
 * Edmond Rodriguez <erodrig_97@yahoo.com> and
 * Aurelien Jacobs <aurel@gnuage.org>
 *
 * The MR97311A support in gspca/mars.c has been helpful in understanding some
 * of the registers in these cameras.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#define MODULE_NAME "mr97310a"

#include "gspca.h"

#define CAM_TYPE_CIF			0
#define CAM_TYPE_VGA			1

#define MR97310A_BRIGHTNESS_DEFAULT	0

#define MR97310A_EXPOSURE_MIN		0
#define MR97310A_EXPOSURE_MAX		4095
#define MR97310A_EXPOSURE_DEFAULT	1000

#define MR97310A_GAIN_MIN		0
#define MR97310A_GAIN_MAX		31
#define MR97310A_GAIN_DEFAULT		25

#define MR97310A_CONTRAST_MIN		0
#define MR97310A_CONTRAST_MAX		31
#define MR97310A_CONTRAST_DEFAULT	23

#define MR97310A_CS_GAIN_MIN		0
#define MR97310A_CS_GAIN_MAX		0x7ff
#define MR97310A_CS_GAIN_DEFAULT	0x110

#define MR97310A_CID_CLOCKDIV (V4L2_CTRL_CLASS_USER + 0x1000)
#define MR97310A_MIN_CLOCKDIV_MIN	3
#define MR97310A_MIN_CLOCKDIV_MAX	8
#define MR97310A_MIN_CLOCKDIV_DEFAULT	3

MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>,"
	      "Theodore Kilgore <kilgota@auburn.edu>");
MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
MODULE_LICENSE("GPL");

/* global parameters */
static int force_sensor_type = -1;
module_param(force_sensor_type, int, 0644);
MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)");

/* specific webcam descriptor */
struct sd {
	struct gspca_dev gspca_dev;  /* !! must be the first item */
	struct { /* exposure/min_clockdiv control cluster */
		struct v4l2_ctrl *exposure;
		struct v4l2_ctrl *min_clockdiv;
	};
	u8 sof_read;
	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 adj_colors;
};

struct sensor_w_data {
	u8 reg;
	u8 flags;
	u8 data[16];
	int len;
};

static void sd_stopN(struct gspca_dev *gspca_dev);

static const struct v4l2_pix_format vga_mode[] = {
	{160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
		.bytesperline = 160,
		.sizeimage = 160 * 120,
		.colorspace = V4L2_COLORSPACE_SRGB,
		.priv = 4},
	{176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
		.bytesperline = 176,
		.sizeimage = 176 * 144,
		.colorspace = V4L2_COLORSPACE_SRGB,
		.priv = 3},
	{320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
		.bytesperline = 320,
		.sizeimage = 320 * 240,
		.colorspace = V4L2_COLORSPACE_SRGB,
		.priv = 2},
	{352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
		.bytesperline = 352,
		.sizeimage = 352 * 288,
		.colorspace = V4L2_COLORSPACE_SRGB,
		.priv = 1},
	{640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
		.bytesperline = 640,
		.sizeimage = 640 * 480,
		.colorspace = V4L2_COLORSPACE_SRGB,
		.priv = 0},
};

/* the bytes to write are in gspca_dev->usb_buf */
static int mr_write(struct gspca_dev *gspca_dev, int len)
{
	int rc;

	rc = usb_bulk_msg(gspca_dev->dev,
			  usb_sndbulkpipe(gspca_dev->dev, 4),
			  gspca_dev->usb_buf, len, NULL, 500);
	if (rc < 0)
		pr_err("reg write [%02x] error %d\n",
		       gspca_dev->usb_buf[0], rc);
	return rc;
}

/* the bytes are read into gspca_dev->usb_buf */
static int mr_read(struct gspca_dev *gspca_dev, int len)
{
	int rc;

	rc = usb_bulk_msg(gspca_dev->dev,
			  usb_rcvbulkpipe(gspca_dev->dev, 3),
			  gspca_dev->usb_buf, len, NULL, 500);
	if (rc < 0)
		pr_err("reg read [%02x] error %d\n",
		       gspca_dev->usb_buf[0], rc);
	return rc;
}

static int sensor_write_reg(struct gspca_dev *gspca_dev, u8 reg, u8 flags,
	const u8 *data, int len)
{
	gspca_dev->usb_buf[0] = 0x1f;
	gspca_dev->usb_buf[1] = flags;
	gspca_dev->usb_buf[2] = reg;
	memcpy(gspca_dev->usb_buf + 3, data, len);

	return mr_write(gspca_dev, len + 3);
}

static int sensor_write_regs(struct gspca_dev *gspca_dev,
	const struct sensor_w_data *data, int len)
{
	int i, rc;

	for (i = 0; i < len; i++) {
		rc = sensor_write_reg(gspca_dev, data[i].reg, data[i].flags,
					  data[i].data, data[i].len);
		if (rc < 0)
			return rc;
	}

	return 0;
}

static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data)
{
	struct sd *sd = (struct sd *) gspca_dev;
	u8 buf, confirm_reg;
	int rc;

	buf = data;
	if (sd->cam_type == CAM_TYPE_CIF) {
		rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
		confirm_reg = sd->sensor_type ? 0x13 : 0x11;
	} else {
		rc = sensor_write_reg(gspca_dev, reg, 0x00, &buf, 1);
		confirm_reg = 0x11;
	}
	if (rc < 0)
		return rc;

	buf = 0x01;
	rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1);
	if (rc < 0)
		return rc;

	return 0;
}

static int cam_get_response16(struct gspca_dev *gspca_dev, u8 reg, int verbose)
{
	int err_code;

	gspca_dev->usb_buf[0] = reg;
	err_code = mr_write(gspca_dev, 1);
	if (err_code < 0)
		return err_code;

	err_code = mr_read(gspca_dev, 16);
	if (err_code < 0)
		return err_code;

	if (verbose)
		PDEBUG(D_PROBE, "Register: %02x reads %02x%02x%02x", reg,
		       gspca_dev->usb_buf[0],
		       gspca_dev->usb_buf[1],
		       gspca_dev->usb_buf[2]);

	return 0;
}

static int zero_the_pointer(struct gspca_dev *gspca_dev)
{
	__u8 *data = gspca_dev->usb_buf;
	int err_code;
	u8 status = 0;
	int tries = 0;

	err_code = cam_get_response16(gspca_dev, 0x21, 0);
	if (err_code < 0)
		return err_code;

	data[0] = 0x19;
	data[1] = 0x51;
	err_code = mr_write(gspca_dev, 2);
	if (err_code < 0)
		return err_code;

	err_code = cam_get_response16(gspca_dev, 0x21, 0);
	if (err_code < 0)
		return err_code;

	data[0] = 0x19;
	data[1] = 0xba;
	err_code = mr_write(gspca_dev, 2);
	if (err_code < 0)
		return err_code;

	err_code = cam_get_response16(gspca_dev, 0x21, 0);
	if (err_code < 0)
		return err_code;

	data[0] = 0x19;
	data[1] = 0x00;
	err_code = mr_write(gspca_dev, 2);
	if (err_code < 0)
		return err_code;

	err_code = cam_get_response16(gspca_dev, 0x21, 0);
	if (err_code < 0)
		return err_code;

	data[0] = 0x19;
	data[1] = 0x00;
	err_code = mr_write(gspca_dev, 2);
	if (err_code < 0)
		return err_code;

	while (status != 0x0a && tries < 256) {
		err_code = cam_get_response16(gspca_dev, 0x21, 0);
		status = data[0];
		tries++;
		if (err_code < 0)
			return err_code;
	}
	if (status != 0x0a)
		PERR("status is %02x", status);

	tries = 0;
	while (tries < 4) {
		data[0] = 0x19;
		data[1] = 0x00;
		err_code = mr_write(gspca_dev, 2);
		if (err_code < 0)
			return err_code;

		err_code = cam_get_response16(gspca_dev, 0x21, 0);
		status = data[0];
		tries++;
		if (err_code < 0)
			return err_code;
	}

	data[0] = 0x19;
	err_code = mr_write(gspca_dev, 1);
	if (err_code < 0)
		return err_code;

	err_code = mr_read(gspca_dev, 16);
	if (err_code < 0)
		return err_code;

	return 0;
}

static int stream_start(struct gspca_dev *gspca_dev)
{
	gspca_dev->usb_buf[0] = 0x01;
	gspca_dev->usb_buf[1] = 0x01;
	return mr_write(gspca_dev, 2);
}

static void stream_stop(struct gspca_dev *gspca_dev)
{
	gspca_dev->usb_buf[0] = 0x01;
	gspca_dev->usb_buf[1] = 0x00;
	if (mr_write(gspca_dev, 2) < 0)
		PERR("Stream Stop failed");
}

static void lcd_stop(struct gspca_dev *gspca_dev)
{
	gspca_dev->usb_buf[0] = 0x19;
	gspca_dev->usb_buf[1] = 0x54;
	if (mr_write(gspca_dev, 2) < 0)
		PERR("LCD Stop failed");
}

static int isoc_enable(struct gspca_dev *gspca_dev)
{
	gspca_dev->usb_buf[0] = 0x00;
	gspca_dev->usb_buf[1] = 0x4d;  /* ISOC transferring enable... */
	return mr_write(gspca_dev, 2);
}

/* This function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
		     const struct usb_device_id *id)
{
	struct sd *sd = (struct sd *) gspca_dev;
	struct cam *cam;
	int err_code;

	cam = &gspca_dev->cam;
	cam->cam_mode = vga_mode;
	cam->nmodes = ARRAY_SIZE(vga_mode);
	sd->do_lcd_stop = 0;

	/* Several of the supported CIF cameras share the same USB ID but
	 * require different initializations and different control settings.
	 * The same is true of the VGA cameras. Therefore, we are forced
	 * to start the initialization process in order to determine which
	 * camera is present. Some of the supported cameras require the
	 * memory pointer to be set to 0 as the very first item of business
	 * or else they will not stream. So we do that immediately.
	 */
	err_code = zero_the_pointer(gspca_dev);
	if (err_code < 0)
		return err_code;

	err_code = stream_start(gspca_dev);
	if (err_code < 0)
		return err_code;

	/* Now, the query for sensor type. */
	err_code = cam_get_response16(gspca_dev, 0x07, 1);
	if (err_code < 0)
		return err_code;

	if (id->idProduct == 0x0110 || id->idProduct == 0x010e) {
		sd->cam_type = CAM_TYPE_CIF;
		cam->nmodes--;
		/*
		 * All but one of the known CIF cameras share the same USB ID,
		 * but two different init routines are in use, and the control
		 * settings are different, too. We need to detect which camera
		 * of the two known varieties is connected!
		 *
		 * A list of known CIF cameras follows. They all report either
		 * 0200 for type 0 or 0300 for type 1.
		 * If you have another to report, please do
		 *
		 * Name		sd->sensor_type		reported by
		 *
		 * Sakar 56379 Spy-shot	0		T. Kilgore
		 * Innovage		0		T. Kilgore
		 * Vivitar Mini		0		H. De Goede
		 * Vivitar Mini		0		E. Rodriguez
		 * Vivitar Mini		1		T. Kilgore
		 * Elta-Media 8212dc	1		T. Kaiser
		 * Philips dig. keych.	1		T. Kilgore
		 * Trust Spyc@m 100	1		A. Jacobs
		 */
		switch (gspca_dev->usb_buf[0]) {
		case 2:
			sd->sensor_type = 0;
			break;
		case 3:
			sd->sensor_type = 1;
			break;
		default:
			pr_err("Unknown CIF Sensor id : %02x\n",
			       gspca_dev->usb_buf[1]);
			return -ENODEV;
		}
		PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
		       sd->sensor_type);
	} else {
		sd->cam_type = CAM_TYPE_VGA;

		/*
		 * Here is a table of the responses to the query for sensor
		 * type, from the known MR97310A VGA cameras. Six different
		 * cameras of which five share the same USB ID.
		 *
		 * Name			gspca_dev->usb_buf[]	sd->sensor_type
		 *				sd->do_lcd_stop
		 * Aiptek Pencam VGA+	0300		0		1
		 * ION digital		0300		0		1
		 * Argus DC-1620	0450		1		0
		 * Argus QuickClix	0420		1		1
		 * Sakar 77379 Digital	0350		0		1
		 * Sakar 1638x CyberPix	0120		0		2
		 *
		 * Based upon these results, we assume default settings
		 * and then correct as necessary, as follows.
		 *
		 */

		sd->sensor_type = 1;
		sd->do_lcd_stop = 0;
		sd->adj_colors = 0;
		if (gspca_dev->usb_buf[0] == 0x01) {
			sd->sensor_type = 2;
		} else if ((gspca_dev->usb_buf[0] != 0x03) &&
					(gspca_dev->usb_buf[0] != 0x04)) {
			pr_err("Unknown VGA Sensor id Byte 0: %02x\n",
			       gspca_dev->usb_buf[0]);
			pr_err("Defaults assumed, may not work\n");
			pr_err("Please report this\n");
		}
		/* Sakar Digital color needs to be adjusted. */
		if ((gspca_dev->usb_buf[0] == 0x03) &&
					(gspca_dev->usb_buf[1] == 0x50))
			sd->adj_colors = 1;
		if (gspca_dev->usb_buf[0] == 0x04) {
			sd->do_lcd_stop = 1;
			switch (gspca_dev->usb_buf[1]) {
			case 0x50:
				sd->sensor_type = 0;
				PDEBUG(D_PROBE, "sensor_type corrected to 0");
				break;
			case 0x20:
				/* Nothing to do here. */
				break;
			default:
				pr_err("Unknown VGA Sensor id Byte 1: %02x\n",
				       gspca_dev->usb_buf[1]);
				pr_err("Defaults assumed, may not work\n");
				pr_err("Please report this\n");
			}
		}
		PDEBUG(D_PROBE, "MR97310A VGA camera detected, sensor: %d",
		       sd->sensor_type);
	}
	/* Stop streaming as we've started it only to probe the sensor type. */
	sd_stopN(gspca_dev);

	if (force_sensor_type != -1) {
		sd->sensor_type = !!force_sensor_type;
		PDEBUG(D_PROBE, "Forcing sensor type to: %d",
		       sd->sensor_type);
	}

	return 0;
}

/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
	return 0;
}

static int start_cif_cam(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *) gspca_dev;
	__u8 *data = gspca_dev->usb_buf;
	int err_code;
	static const __u8 startup_string[] = {
		0x00,
		0x0d,
		0x01,
		0x00, /* Hsize/8 for 352 or 320 */
		0x00, /* Vsize/4 for 288 or 240 */
		0x13, /* or 0xbb, depends on sensor */
		0x00, /* Hstart, depends on res. */
		0x00, /* reserved ? */
		0x00, /* Vstart, depends on res. and sensor */
		0x50, /* 0x54 to get 176 or 160 */
		0xc0
	};

	/* Note: Some of the above descriptions guessed from MR97113A driver */

	memcpy(data, startup_string, 11);
	if (sd->sensor_type)
		data[5] = 0xbb;

	switch (gspca_dev->width) {
	case 160:
		data[9] |= 0x04;  /* reg 8, 2:1 scale down from 320 */
		/* fall thru */
	case 320:
	default:
		data[3] = 0x28;			   /* reg 2, H size/8 */
		data[4] = 0x3c;			   /* reg 3, V size/4 */
		data[6] = 0x14;			   /* reg 5, H start  */
		data[8] = 0x1a + sd->sensor_type;  /* reg 7, V start  */
		break;
	case 176:
		data[9] |= 0x04;  /* reg 8, 2:1 scale down from 352 */
		/* fall thru */
	case 352:
		data[3] = 0x2c;			   /* reg 2, H size/8 */
		data[4] = 0x48;			   /* reg 3, V size/4 */
		data[6] = 0x06;			   /* reg 5, H start  */
		data[8] = 0x06 - sd->sensor_type;  /* reg 7, V start  */
		break;
	}
	err_code = mr_write(gspca_dev, 11);
	if (err_code < 0)
		return err_code;

	if (!sd->sensor_type) {
		static const struct sensor_w_data cif_sensor0_init_data[] = {
			{0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01,
				      0x0f, 0x14, 0x0f, 0x10}, 8},
			{0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5},
			{0x12, 0x00, {0x07}, 1},
			{0x1f, 0x00, {0x06}, 1},
			{0x27, 0x00, {0x04}, 1},
			{0x29, 0x00, {0x0c}, 1},
			{0x40, 0x00, {0x40, 0x00, 0x04}, 3},
			{0x50, 0x00, {0x60}, 1},
			{0x60, 0x00, {0x06}, 1},
			{0x6b, 0x00, {0x85, 0x85, 0xc8, 0xc8, 0xc8, 0xc8}, 6},
			{0x72, 0x00, {0x1e, 0x56}, 2},
			{0x75, 0x00, {0x58, 0x40, 0xa2, 0x02, 0x31, 0x02,
				      0x31, 0x80, 0x00}, 9},
			{0x11, 0x00, {0x01}, 1},
			{0, 0, {0}, 0}
		};
		err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data,
					 ARRAY_SIZE(cif_sensor0_init_data));
	} else {	/* sd->sensor_type = 1 */
		static const struct sensor_w_data cif_sensor1_init_data[] = {
			/* Reg 3,4, 7,8 get set by the controls */
			{0x02, 0x00, {0x10}, 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, {0x07}, 1},
			{0x0e, 0x02, {0x0c}, 1},
			{0x0f, 0x00, {0x00}, 1},
			{0x10, 0x00, {0x06}, 1},
			{0x11, 0x00, {0x07}, 1},
			{0x12, 0x00, {0x00}, 1},
			{0x13, 0x00, {0x01}, 1},
			{0, 0, {0}, 0}
		};
		/* Without this command the cam won't work with USB-UHCI */
		gspca_dev->usb_buf[0] = 0x0a;
		gspca_dev->usb_buf[1] = 0x00;
		err_code = mr_write(gspca_dev, 2);
		if (err_code < 0)
			return err_code;
		err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
					 ARRAY_SIZE(cif_sensor1_init_data));
	}
	return err_code;
}

static int start_vga_cam(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *) gspca_dev;
	__u8 *data = gspca_dev->usb_buf;
	int err_code;
	static const __u8 startup_string[] =
		{0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b, 0x00, 0x00,
		 0x00, 0x50, 0xc0};
	/* What some of these mean is explained in start_cif_cam(), above */

	memcpy(data, startup_string, 11);
	if (!sd->sensor_type) {
		data[5]  = 0x00;
		data[10] = 0x91;
	}
	if (sd->sensor_type == 2) {
		data[5]  = 0x00;
		data[10] = 0x18;
	}

	switch (gspca_dev->width) {
	case 160:
		data[9] |= 0x0c;  /* reg 8, 4:1 scale down */
		/* fall thru */
	case 320:
		data[9] |= 0x04;  /* reg 8, 2:1 scale down */
		/* fall thru */
	case 640:
	default:
		data[3] = 0x50;  /* reg 2, H size/8 */
		data[4] = 0x78;  /* reg 3, V size/4 */
		data[6] = 0x04;  /* reg 5, H start */
		data[8] = 0x03;  /* reg 7, V start */
		if (sd->sensor_type == 2) {
			data[6] = 2;
			data[8] = 1;
		}
		if (sd->do_lcd_stop)
			data[8] = 0x04;  /* Bayer tile shifted */
		break;

	case 176:
		data[9] |= 0x04;  /* reg 8, 2:1 scale down */
		/* fall thru */
	case 352:
		data[3] = 0x2c;  /* reg 2, H size */
		data[4] = 0x48;  /* reg 3, V size */
		data[6] = 0x94;  /* reg 5, H start */
		data[8] = 0x63;  /* reg 7, V start */
		if (sd->do_lcd_stop)
			data[8] = 0x64;  /* Bayer tile shifted */
		break;
	}

	err_code = mr_write(gspca_dev, 11);
	if (err_code < 0)
		return err_code;

	if (!sd->sensor_type) {
		static const struct sensor_w_data vga_sensor0_init_data[] = {
			{0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
			{0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
			{0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4},
			{0x25, 0x00, {0x03, 0xa9, 0x80}, 3},
			{0x30, 0x00, {0x30, 0x18, 0x10, 0x18}, 4},
			{0, 0, {0}, 0}
		};
		err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
					 ARRAY_SIZE(vga_sensor0_init_data));
	} else if (sd->sensor_type == 1) {
		static const struct sensor_w_data color_adj[] = {
			{0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
				/* adjusted blue, green, red gain correct
				   too much blue from the Sakar Digital */
				0x05, 0x01, 0x04}, 8}
		};

		static const struct sensor_w_data color_no_adj[] = {
			{0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
				/* default blue, green, red gain settings */
				0x07, 0x00, 0x01}, 8}
		};

		static const struct sensor_w_data vga_sensor1_init_data[] = {
			{0x11, 0x04, {0x01}, 1},
			{0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01,
			/* These settings may be better for some cameras */
			/* {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01, */
				0x00, 0x0a}, 7},
			{0x11, 0x04, {0x01}, 1},
			{0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
			{0x11, 0x04, {0x01}, 1},
			{0, 0, {0}, 0}
		};

		if (sd->adj_colors)
			err_code = sensor_write_regs(gspca_dev, color_adj,
					 ARRAY_SIZE(color_adj));
		else
			err_code = sensor_write_regs(gspca_dev, color_no_adj,
					 ARRAY_SIZE(color_no_adj));

		if (err_code < 0)
			return err_code;

		err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
					 ARRAY_SIZE(vga_sensor1_init_data));
	} else {	/* sensor type == 2 */
		static const struct sensor_w_data vga_sensor2_init_data[] = {

			{0x01, 0x00, {0x48}, 1},
			{0x02, 0x00, {0x22}, 1},
			/* Reg 3 msb and 4 is lsb of the exposure setting*/
			{0x05, 0x00, {0x10}, 1},
			{0x06, 0x00, {0x00}, 1},
			{0x07, 0x00, {0x00}, 1},
			{0x08, 0x00, {0x00}, 1},
			{0x09, 0x00, {0x00}, 1},
			/* The following are used in the gain control
			 * which is BTW completely borked in the OEM driver
			 * The values for each color go from 0 to 0x7ff
			 *{0x0a, 0x00, {0x01}, 1},  green1 gain msb
			 *{0x0b, 0x00, {0x10}, 1},  green1 gain lsb
			 *{0x0c, 0x00, {0x01}, 1},  red gain msb
			 *{0x0d, 0x00, {0x10}, 1},  red gain lsb
			 *{0x0e, 0x00, {0x01}, 1},  blue gain msb
			 *{0x0f, 0x00, {0x10}, 1},  blue gain lsb
			 *{0x10, 0x00, {0x01}, 1}, green2 gain msb
			 *{0x11, 0x00, {0x10}, 1}, green2 gain lsb
			 */
			{0x12, 0x00, {0x00}, 1},
			{0x13, 0x00, {0x04}, 1}, /* weird effect on colors */
			{0x14, 0x00, {0x00}, 1},
			{0x15, 0x00, {0x06}, 1},
			{0x16, 0x00, {0x01}, 1},
			{0x17, 0x00, {0xe2}, 1}, /* vertical alignment */
			{0x18, 0x00, {0x02}, 1},
			{0x19, 0x00, {0x82}, 1}, /* don't mess with */
			{0x1a, 0x00, {0x00}, 1},
			{0x1b, 0x00, {0x20}, 1},
			/* {0x1c, 0x00, {0x17}, 1}, contrast control */
			{0x1d, 0x00, {0x80}, 1}, /* moving causes a mess */
			{0x1e, 0x00, {0x08}, 1}, /* moving jams the camera */
			{0x1f, 0x00, {0x0c}, 1},
			{0x20, 0x00, {0x00}, 1},
			{0, 0, {0}, 0}
		};
		err_code = sensor_write_regs(gspca_dev, vga_sensor2_init_data,
					 ARRAY_SIZE(vga_sensor2_init_data));
	}
	return err_code;
}

static int sd_start(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *) gspca_dev;
	int err_code;

	sd->sof_read = 0;

	/* Some of the VGA cameras require the memory pointer
	 * to be set to 0 again. We have been forced to start the
	 * stream in sd_config() to detect the hardware, and closed it.
	 * Thus, we need here to do a completely fresh and clean start. */
	err_code = zero_the_pointer(gspca_dev);
	if (err_code < 0)
		return err_code;

	err_code = stream_start(gspca_dev);
	if (err_code < 0)
		return err_code;

	if (sd->cam_type == CAM_TYPE_CIF) {
		err_code = start_cif_cam(gspca_dev);
	} else {
		err_code = start_vga_cam(gspca_dev);
	}
	if (err_code < 0)
		return err_code;

	return isoc_enable(gspca_dev);
}

static void sd_stopN(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *) gspca_dev;

	stream_stop(gspca_dev);
	/* Not all the cams need this, but even if not, probably a good idea */
	zero_the_pointer(gspca_dev);
	if (sd->do_lcd_stop)
		lcd_stop(gspca_dev);
}

static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
{
	struct sd *sd = (struct sd *) gspca_dev;
	u8 sign_reg = 7;  /* This reg and the next one used on CIF cams. */
	u8 value_reg = 8; /* VGA cams seem to use regs 0x0b and 0x0c */
	static const u8 quick_clix_table[] =
	/*	  0  1  2   3  4  5  6  7  8  9  10  11  12  13  14  15 */
		{ 0, 4, 8, 12, 1, 2, 3, 5, 6, 9,  7, 10, 13, 11, 14, 15};
	if (sd->cam_type == CAM_TYPE_VGA) {
		sign_reg += 4;
		value_reg += 4;
	}

	/* Note register 7 is also seen as 0x8x or 0xCx in some dumps */
	if (val > 0) {
		sensor_write1(gspca_dev, sign_reg, 0x00);
	} else {
		sensor_write1(gspca_dev, sign_reg, 0x01);
		val = 257 - val;
	}
	/* Use lookup table for funky Argus QuickClix brightness */
	if (sd->do_lcd_stop)
		val = quick_clix_table[val];

	sensor_write1(gspca_dev, value_reg, val);
}

static void setexposure(struct gspca_dev *gspca_dev, s32 expo, s32 min_clockdiv)
{
	struct sd *sd = (struct sd *) gspca_dev;
	int exposure = MR97310A_EXPOSURE_DEFAULT;
	u8 buf[2];

	if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1) {
		/* This cam does not like exposure settings < 300,
		   so scale 0 - 4095 to 300 - 4095 */
		exposure = (expo * 9267) / 10000 + 300;
		sensor_write1(gspca_dev, 3, exposure >> 4);
		sensor_write1(gspca_dev, 4, exposure & 0x0f);
	} else if (sd->sensor_type == 2) {
		exposure = expo;
		exposure >>= 3;
		sensor_write1(gspca_dev, 3, exposure >> 8);
		sensor_write1(gspca_dev, 4, exposure & 0xff);
	} else {
		/* We have both a clock divider and an exposure register.
		   We first calculate the clock divider, as that determines
		   the maximum exposure and then we calculate the exposure
		   register setting (which goes from 0 - 511).

		   Note our 0 - 4095 exposure is mapped to 0 - 511
		   milliseconds exposure time */
		u8 clockdiv = (60 * expo + 7999) / 8000;

		/* Limit framerate to not exceed usb bandwidth */
		if (clockdiv < min_clockdiv && gspca_dev->width >= 320)
			clockdiv = min_clockdiv;
		else if (clockdiv < 2)
			clockdiv = 2;

		if (sd->cam_type == CAM_TYPE_VGA && clockdiv < 4)
			clockdiv = 4;

		/* Frame exposure time in ms = 1000 * clockdiv / 60 ->
		exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */
		exposure = (60 * 511 * expo) / (8000 * clockdiv);
		if (exposure > 511)
			exposure = 511;

		/* exposure register value is reversed! */
		exposure = 511 - exposure;

		buf[0] = exposure & 0xff;
		buf[1] = exposure >> 8;
		sensor_write_reg(gspca_dev, 0x0e, 0, buf, 2);
		sensor_write1(gspca_dev, 0x02, clockdiv);
	}
}

static void setgain(struct gspca_dev *gspca_dev, s32 val)
{
	struct sd *sd = (struct sd *) gspca_dev;
	u8 gainreg;

	if (sd->cam_type == CAM_TYPE_CIF && sd->sensor_type == 1)
		sensor_write1(gspca_dev, 0x0e, val);
	else if (sd->cam_type == CAM_TYPE_VGA && sd->sensor_type == 2)
		for (gainreg = 0x0a; gainreg < 0x11; gainreg += 2) {
			sensor_write1(gspca_dev, gainreg, val >> 8);
			sensor_write1(gspca_dev, gainreg + 1, val & 0xff);
		}
	else
		sensor_write1(gspca_dev, 0x10, val);
}

static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
{
	sensor_write1(gspca_dev, 0x1c, val);
}

static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
{
	struct gspca_dev *gspca_dev =
		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
	struct sd *sd = (struct sd *)gspca_dev;

	gspca_dev->usb_err = 0;

	if (!gspca_dev->streaming)
		return 0;

	switch (ctrl->id) {
	case V4L2_CID_BRIGHTNESS:
		setbrightness(gspca_dev, ctrl->val);
		break;
	case V4L2_CID_CONTRAST:
		setcontrast(gspca_dev, ctrl->val);
		break;
	case V4L2_CID_EXPOSURE:
		setexposure(gspca_dev, sd->exposure->val,
			    sd->min_clockdiv ? sd->min_clockdiv->val : 0);
		break;
	case V4L2_CID_GAIN:
		setgain(gspca_dev, ctrl->val);
		break;
	}
	return gspca_dev->usb_err;
}

static const struct v4l2_ctrl_ops sd_ctrl_ops = {
	.s_ctrl = sd_s_ctrl,
};

static int sd_init_controls(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *)gspca_dev;
	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
	static const struct v4l2_ctrl_config clockdiv = {
		.ops = &sd_ctrl_ops,
		.id = MR97310A_CID_CLOCKDIV,
		.type = V4L2_CTRL_TYPE_INTEGER,
		.name = "Minimum Clock Divider",
		.min = MR97310A_MIN_CLOCKDIV_MIN,
		.max = MR97310A_MIN_CLOCKDIV_MAX,
		.step = 1,
		.def = MR97310A_MIN_CLOCKDIV_DEFAULT,
	};
	bool has_brightness = false;
	bool has_argus_brightness = false;
	bool has_contrast = false;
	bool has_gain = false;
	bool has_cs_gain = false;
	bool has_exposure = false;
	bool has_clockdiv = false;

	gspca_dev->vdev.ctrl_handler = hdl;
	v4l2_ctrl_handler_init(hdl, 4);

	/* Setup controls depending on camera type */
	if (sd->cam_type == CAM_TYPE_CIF) {
		/* No brightness for sensor_type 0 */
		if (sd->sensor_type == 0)
			has_exposure = has_gain = has_clockdiv = true;
		else
			has_exposure = has_gain = has_brightness = true;
	} else {
		/* All controls need to be disabled if VGA sensor_type is 0 */
		if (sd->sensor_type == 0)
			; /* no controls! */
		else if (sd->sensor_type == 2)
			has_exposure = has_cs_gain = has_contrast = true;
		else if (sd->do_lcd_stop)
			has_exposure = has_gain = has_argus_brightness =
				has_clockdiv = true;
		else
			has_exposure = has_gain = has_brightness =
				has_clockdiv = true;
	}

	/* Separate brightness control description for Argus QuickClix as it has
	 * different limits from the other mr97310a cameras, and separate gain
	 * control for Sakar CyberPix camera. */
	/*
	 * This control is disabled for CIF type 1 and VGA type 0 cameras.
	 * It does not quite act linearly for the Argus QuickClix camera,
	 * but it does control brightness. The values are 0 - 15 only, and
	 * the table above makes them act consecutively.
	 */
	if (has_brightness)
		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
			V4L2_CID_BRIGHTNESS, -254, 255, 1,
			MR97310A_BRIGHTNESS_DEFAULT);
	else if (has_argus_brightness)
		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
			V4L2_CID_BRIGHTNESS, 0, 15, 1,
			MR97310A_BRIGHTNESS_DEFAULT);
	if (has_contrast)
		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
			V4L2_CID_CONTRAST, MR97310A_CONTRAST_MIN,
			MR97310A_CONTRAST_MAX, 1, MR97310A_CONTRAST_DEFAULT);
	if (has_gain)
		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
			V4L2_CID_GAIN, MR97310A_GAIN_MIN, MR97310A_GAIN_MAX,
			1, MR97310A_GAIN_DEFAULT);
	else if (has_cs_gain)
		v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_GAIN,
			MR97310A_CS_GAIN_MIN, MR97310A_CS_GAIN_MAX,
			1, MR97310A_CS_GAIN_DEFAULT);
	if (has_exposure)
		sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
			V4L2_CID_EXPOSURE, MR97310A_EXPOSURE_MIN,
			MR97310A_EXPOSURE_MAX, 1, MR97310A_EXPOSURE_DEFAULT);
	if (has_clockdiv)
		sd->min_clockdiv = v4l2_ctrl_new_custom(hdl, &clockdiv, NULL);

	if (hdl->error) {
		pr_err("Could not initialize controls\n");
		return hdl->error;
	}
	if (has_exposure && has_clockdiv)
		v4l2_ctrl_cluster(2, &sd->exposure);
	return 0;
}

/* Include pac common sof detection functions */
#include "pac_common.h"

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;
	unsigned char *sof;

	sof = pac_find_sof(gspca_dev, &sd->sof_read, data, len);
	if (sof) {
		int n;

		/* finish decoding current frame */
		n = sof - data;
		if (n > sizeof pac_sof_marker)
			n -= sizeof pac_sof_marker;
		else
			n = 0;
		gspca_frame_add(gspca_dev, LAST_PACKET,
					data, n);
		/* Start next frame. */
		gspca_frame_add(gspca_dev, FIRST_PACKET,
			pac_sof_marker, sizeof pac_sof_marker);
		len -= sof - data;
		data = sof;
	}
	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
}

/* sub-driver description */
static const struct sd_desc sd_desc = {
	.name = MODULE_NAME,
	.config = sd_config,
	.init = sd_init,
	.init_controls = sd_init_controls,
	.start = sd_start,
	.stopN = sd_stopN,
	.pkt_scan = sd_pkt_scan,
};

/* -- module initialisation -- */
static const struct usb_device_id device_table[] = {
	{USB_DEVICE(0x08ca, 0x0110)},	/* Trust Spyc@m 100 */
	{USB_DEVICE(0x08ca, 0x0111)},	/* Aiptek Pencam VGA+ */
	{USB_DEVICE(0x093a, 0x010f)},	/* All other known MR97310A VGA cams */
	{USB_DEVICE(0x093a, 0x010e)},	/* All known MR97310A CIF cams */
	{}
};
MODULE_DEVICE_TABLE(usb, device_table);

/* -- device connect -- */
static int sd_probe(struct usb_interface *intf,
		    const struct usb_device_id *id)
{
	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
			       THIS_MODULE);
}

static struct usb_driver sd_driver = {
	.name = MODULE_NAME,
	.id_table = device_table,
	.probe = sd_probe,
	.disconnect = gspca_disconnect,
#ifdef CONFIG_PM
	.suspend = gspca_suspend,
	.resume = gspca_resume,
	.reset_resume = gspca_resume,
#endif
};

module_usb_driver(sd_driver);
