PageRenderTime 285ms CodeModel.GetById 31ms app.highlight 227ms RepoModel.GetById 1ms app.codeStats 1ms

/drivers/media/video/gspca/spca561.c

https://bitbucket.org/slukk/jb-tsm-kernel-4.2
C | 1118 lines | 894 code | 117 blank | 107 comment | 61 complexity | 5c856564da2f34e7aebc8b95225e7394 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
   1/*
   2 * Sunplus spca561 subdriver
   3 *
   4 * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr
   5 *
   6 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21 */
  22
  23#define MODULE_NAME "spca561"
  24
  25#include <linux/input.h>
  26#include "gspca.h"
  27
  28MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
  29MODULE_DESCRIPTION("GSPCA/SPCA561 USB Camera Driver");
  30MODULE_LICENSE("GPL");
  31
  32/* specific webcam descriptor */
  33struct sd {
  34	struct gspca_dev gspca_dev;	/* !! must be the first item */
  35
  36	__u16 exposure;			/* rev12a only */
  37#define EXPOSURE_MIN 1
  38#define EXPOSURE_DEF 700		/* == 10 fps */
  39#define EXPOSURE_MAX (2047 + 325)	/* see setexposure */
  40
  41	__u8 contrast;			/* rev72a only */
  42#define CONTRAST_MIN 0x00
  43#define CONTRAST_DEF 0x20
  44#define CONTRAST_MAX 0x3f
  45
  46	__u8 brightness;		/* rev72a only */
  47#define BRIGHTNESS_MIN 0
  48#define BRIGHTNESS_DEF 0x20
  49#define BRIGHTNESS_MAX 0x3f
  50
  51	__u8 white;
  52#define HUE_MIN 1
  53#define HUE_DEF 0x40
  54#define HUE_MAX 0x7f
  55
  56	__u8 autogain;
  57#define AUTOGAIN_MIN 0
  58#define AUTOGAIN_DEF 1
  59#define AUTOGAIN_MAX 1
  60
  61	__u8 gain;			/* rev12a only */
  62#define GAIN_MIN 0
  63#define GAIN_DEF 63
  64#define GAIN_MAX 255
  65
  66#define EXPO12A_DEF 3
  67	__u8 expo12a;		/* expo/gain? for rev 12a */
  68
  69	__u8 chip_revision;
  70#define Rev012A 0
  71#define Rev072A 1
  72
  73	signed char ag_cnt;
  74#define AG_CNT_START 13
  75};
  76
  77static const struct v4l2_pix_format sif_012a_mode[] = {
  78	{160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
  79		.bytesperline = 160,
  80		.sizeimage = 160 * 120,
  81		.colorspace = V4L2_COLORSPACE_SRGB,
  82		.priv = 3},
  83	{176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
  84		.bytesperline = 176,
  85		.sizeimage = 176 * 144,
  86		.colorspace = V4L2_COLORSPACE_SRGB,
  87		.priv = 2},
  88	{320, 240, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
  89		.bytesperline = 320,
  90		.sizeimage = 320 * 240 * 4 / 8,
  91		.colorspace = V4L2_COLORSPACE_SRGB,
  92		.priv = 1},
  93	{352, 288, V4L2_PIX_FMT_SPCA561, V4L2_FIELD_NONE,
  94		.bytesperline = 352,
  95		.sizeimage = 352 * 288 * 4 / 8,
  96		.colorspace = V4L2_COLORSPACE_SRGB,
  97		.priv = 0},
  98};
  99
 100static const struct v4l2_pix_format sif_072a_mode[] = {
 101	{160, 120, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
 102		.bytesperline = 160,
 103		.sizeimage = 160 * 120,
 104		.colorspace = V4L2_COLORSPACE_SRGB,
 105		.priv = 3},
 106	{176, 144, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
 107		.bytesperline = 176,
 108		.sizeimage = 176 * 144,
 109		.colorspace = V4L2_COLORSPACE_SRGB,
 110		.priv = 2},
 111	{320, 240, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
 112		.bytesperline = 320,
 113		.sizeimage = 320 * 240,
 114		.colorspace = V4L2_COLORSPACE_SRGB,
 115		.priv = 1},
 116	{352, 288, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
 117		.bytesperline = 352,
 118		.sizeimage = 352 * 288,
 119		.colorspace = V4L2_COLORSPACE_SRGB,
 120		.priv = 0},
 121};
 122
 123/*
 124 * Initialization data
 125 * I'm not very sure how to split initialization from open data
 126 * chunks. For now, we'll consider everything as initialization
 127 */
 128/* Frame packet header offsets for the spca561 */
 129#define SPCA561_OFFSET_SNAP 1
 130#define SPCA561_OFFSET_TYPE 2
 131#define SPCA561_OFFSET_COMPRESS 3
 132#define SPCA561_OFFSET_FRAMSEQ   4
 133#define SPCA561_OFFSET_GPIO 5
 134#define SPCA561_OFFSET_USBBUFF 6
 135#define SPCA561_OFFSET_WIN2GRAVE 7
 136#define SPCA561_OFFSET_WIN2RAVE 8
 137#define SPCA561_OFFSET_WIN2BAVE 9
 138#define SPCA561_OFFSET_WIN2GBAVE 10
 139#define SPCA561_OFFSET_WIN1GRAVE 11
 140#define SPCA561_OFFSET_WIN1RAVE 12
 141#define SPCA561_OFFSET_WIN1BAVE 13
 142#define SPCA561_OFFSET_WIN1GBAVE 14
 143#define SPCA561_OFFSET_FREQ 15
 144#define SPCA561_OFFSET_VSYNC 16
 145#define SPCA561_INDEX_I2C_BASE 0x8800
 146#define SPCA561_SNAPBIT 0x20
 147#define SPCA561_SNAPCTRL 0x40
 148
 149static const u16 rev72a_reset[][2] = {
 150	{0x0000, 0x8114},	/* Software GPIO output data */
 151	{0x0001, 0x8114},	/* Software GPIO output data */
 152	{0x0000, 0x8112},	/* Some kind of reset */
 153	{}
 154};
 155static const __u16 rev72a_init_data1[][2] = {
 156	{0x0003, 0x8701},	/* PCLK clock delay adjustment */
 157	{0x0001, 0x8703},	/* HSYNC from cmos inverted */
 158	{0x0011, 0x8118},	/* Enable and conf sensor */
 159	{0x0001, 0x8118},	/* Conf sensor */
 160	{0x0092, 0x8804},	/* I know nothing about these */
 161	{0x0010, 0x8802},	/* 0x88xx registers, so I won't */
 162	{}
 163};
 164static const u16 rev72a_init_sensor1[][2] = {
 165	{0x0001, 0x000d},
 166	{0x0002, 0x0018},
 167	{0x0004, 0x0165},
 168	{0x0005, 0x0021},
 169	{0x0007, 0x00aa},
 170	{0x0020, 0x1504},
 171	{0x0039, 0x0002},
 172	{0x0035, 0x0010},
 173	{0x0009, 0x1049},
 174	{0x0028, 0x000b},
 175	{0x003b, 0x000f},
 176	{0x003c, 0x0000},
 177	{}
 178};
 179static const __u16 rev72a_init_data2[][2] = {
 180	{0x0018, 0x8601},	/* Pixel/line selection for color separation */
 181	{0x0000, 0x8602},	/* Optical black level for user setting */
 182	{0x0060, 0x8604},	/* Optical black horizontal offset */
 183	{0x0002, 0x8605},	/* Optical black vertical offset */
 184	{0x0000, 0x8603},	/* Non-automatic optical black level */
 185	{0x0002, 0x865b},	/* Horizontal offset for valid pixels */
 186	{0x0000, 0x865f},	/* Vertical valid pixels window (x2) */
 187	{0x00b0, 0x865d},	/* Horizontal valid pixels window (x2) */
 188	{0x0090, 0x865e},	/* Vertical valid lines window (x2) */
 189	{0x00e0, 0x8406},	/* Memory buffer threshold */
 190	{0x0000, 0x8660},	/* Compensation memory stuff */
 191	{0x0002, 0x8201},	/* Output address for r/w serial EEPROM */
 192	{0x0008, 0x8200},	/* Clear valid bit for serial EEPROM */
 193	{0x0001, 0x8200},	/* OprMode to be executed by hardware */
 194/* from ms-win */
 195	{0x0000, 0x8611},	/* R offset for white balance */
 196	{0x00fd, 0x8612},	/* Gr offset for white balance */
 197	{0x0003, 0x8613},	/* B offset for white balance */
 198	{0x0000, 0x8614},	/* Gb offset for white balance */
 199/* from ms-win */
 200	{0x0035, 0x8651},	/* R gain for white balance */
 201	{0x0040, 0x8652},	/* Gr gain for white balance */
 202	{0x005f, 0x8653},	/* B gain for white balance */
 203	{0x0040, 0x8654},	/* Gb gain for white balance */
 204	{0x0002, 0x8502},	/* Maximum average bit rate stuff */
 205	{0x0011, 0x8802},
 206
 207	{0x0087, 0x8700},	/* Set master clock (96Mhz????) */
 208	{0x0081, 0x8702},	/* Master clock output enable */
 209
 210	{0x0000, 0x8500},	/* Set image type (352x288 no compression) */
 211	/* Originally was 0x0010 (352x288 compression) */
 212
 213	{0x0002, 0x865b},	/* Horizontal offset for valid pixels */
 214	{0x0003, 0x865c},	/* Vertical offset for valid lines */
 215	{}
 216};
 217static const u16 rev72a_init_sensor2[][2] = {
 218	{0x0003, 0x0121},
 219	{0x0004, 0x0165},
 220	{0x0005, 0x002f},	/* blanking control column */
 221	{0x0006, 0x0000},	/* blanking mode row*/
 222	{0x000a, 0x0002},
 223	{0x0009, 0x1061},	/* setexposure times && pixel clock
 224				 * 0001 0 | 000 0110 0001 */
 225	{0x0035, 0x0014},
 226	{}
 227};
 228
 229/******************** QC Express etch2 stuff ********************/
 230static const __u16 Pb100_1map8300[][2] = {
 231	/* reg, value */
 232	{0x8320, 0x3304},
 233
 234	{0x8303, 0x0125},	/* image area */
 235	{0x8304, 0x0169},
 236	{0x8328, 0x000b},
 237	{0x833c, 0x0001},		/*fixme: win:07*/
 238
 239	{0x832f, 0x1904},		/*fixme: was 0419*/
 240	{0x8307, 0x00aa},
 241	{0x8301, 0x0003},
 242	{0x8302, 0x000e},
 243	{}
 244};
 245static const __u16 Pb100_2map8300[][2] = {
 246	/* reg, value */
 247	{0x8339, 0x0000},
 248	{0x8307, 0x00aa},
 249	{}
 250};
 251
 252static const __u16 spca561_161rev12A_data1[][2] = {
 253	{0x29, 0x8118},		/* Control register (various enable bits) */
 254	{0x08, 0x8114},		/* GPIO: Led off */
 255	{0x0e, 0x8112},		/* 0x0e stream off 0x3e stream on */
 256	{0x00, 0x8102},		/* white balance - new */
 257	{0x92, 0x8804},
 258	{0x04, 0x8802},		/* windows uses 08 */
 259	{}
 260};
 261static const __u16 spca561_161rev12A_data2[][2] = {
 262	{0x21, 0x8118},
 263	{0x10, 0x8500},
 264	{0x07, 0x8601},
 265	{0x07, 0x8602},
 266	{0x04, 0x8501},
 267
 268	{0x07, 0x8201},		/* windows uses 02 */
 269	{0x08, 0x8200},
 270	{0x01, 0x8200},
 271
 272	{0x90, 0x8604},
 273	{0x00, 0x8605},
 274	{0xb0, 0x8603},
 275
 276	/* sensor gains */
 277	{0x07, 0x8601},		/* white balance - new */
 278	{0x07, 0x8602},		/* white balance - new */
 279	{0x00, 0x8610},		/* *red */
 280	{0x00, 0x8611},		/* 3f   *green */
 281	{0x00, 0x8612},		/* green *blue */
 282	{0x00, 0x8613},		/* blue *green */
 283	{0x43, 0x8614},		/* green *red - white balance - was 0x35 */
 284	{0x40, 0x8615},		/* 40   *green - white balance - was 0x35 */
 285	{0x71, 0x8616},		/* 7a   *blue - white balance - was 0x35 */
 286	{0x40, 0x8617},		/* 40   *green - white balance - was 0x35 */
 287
 288	{0x0c, 0x8620},		/* 0c */
 289	{0xc8, 0x8631},		/* c8 */
 290	{0xc8, 0x8634},		/* c8 */
 291	{0x23, 0x8635},		/* 23 */
 292	{0x1f, 0x8636},		/* 1f */
 293	{0xdd, 0x8637},		/* dd */
 294	{0xe1, 0x8638},		/* e1 */
 295	{0x1d, 0x8639},		/* 1d */
 296	{0x21, 0x863a},		/* 21 */
 297	{0xe3, 0x863b},		/* e3 */
 298	{0xdf, 0x863c},		/* df */
 299	{0xf0, 0x8505},
 300	{0x32, 0x850a},
 301/*	{0x99, 0x8700},		 * - white balance - new (removed) */
 302	/* HDG we used to do this in stop0, making the init state and the state
 303	   after a start / stop different, so do this here instead. */
 304	{0x29, 0x8118},
 305	{}
 306};
 307
 308static void reg_w_val(struct usb_device *dev, __u16 index, __u8 value)
 309{
 310	int ret;
 311
 312	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
 313			      0,		/* request */
 314			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 315			      value, index, NULL, 0, 500);
 316	PDEBUG(D_USBO, "reg write: 0x%02x:0x%02x", index, value);
 317	if (ret < 0)
 318		err("reg write: error %d", ret);
 319}
 320
 321static void write_vector(struct gspca_dev *gspca_dev,
 322			const __u16 data[][2])
 323{
 324	struct usb_device *dev = gspca_dev->dev;
 325	int i;
 326
 327	i = 0;
 328	while (data[i][1] != 0) {
 329		reg_w_val(dev, data[i][1], data[i][0]);
 330		i++;
 331	}
 332}
 333
 334/* read 'len' bytes to gspca_dev->usb_buf */
 335static void reg_r(struct gspca_dev *gspca_dev,
 336		  __u16 index, __u16 length)
 337{
 338	usb_control_msg(gspca_dev->dev,
 339			usb_rcvctrlpipe(gspca_dev->dev, 0),
 340			0,			/* request */
 341			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 342			0,			/* value */
 343			index, gspca_dev->usb_buf, length, 500);
 344}
 345
 346/* write 'len' bytes from gspca_dev->usb_buf */
 347static void reg_w_buf(struct gspca_dev *gspca_dev,
 348		      __u16 index, __u16 len)
 349{
 350	usb_control_msg(gspca_dev->dev,
 351			usb_sndctrlpipe(gspca_dev->dev, 0),
 352			0,			/* request */
 353			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
 354			0,			/* value */
 355			index, gspca_dev->usb_buf, len, 500);
 356}
 357
 358static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg)
 359{
 360	int retry = 60;
 361
 362	reg_w_val(gspca_dev->dev, 0x8801, reg);
 363	reg_w_val(gspca_dev->dev, 0x8805, value);
 364	reg_w_val(gspca_dev->dev, 0x8800, value >> 8);
 365	do {
 366		reg_r(gspca_dev, 0x8803, 1);
 367		if (!gspca_dev->usb_buf[0])
 368			return;
 369		msleep(10);
 370	} while (--retry);
 371}
 372
 373static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
 374{
 375	int retry = 60;
 376	__u8 value;
 377
 378	reg_w_val(gspca_dev->dev, 0x8804, 0x92);
 379	reg_w_val(gspca_dev->dev, 0x8801, reg);
 380	reg_w_val(gspca_dev->dev, 0x8802, mode | 0x01);
 381	do {
 382		reg_r(gspca_dev, 0x8803, 1);
 383		if (!gspca_dev->usb_buf[0]) {
 384			reg_r(gspca_dev, 0x8800, 1);
 385			value = gspca_dev->usb_buf[0];
 386			reg_r(gspca_dev, 0x8805, 1);
 387			return ((int) value << 8) | gspca_dev->usb_buf[0];
 388		}
 389		msleep(10);
 390	} while (--retry);
 391	return -1;
 392}
 393
 394static void sensor_mapwrite(struct gspca_dev *gspca_dev,
 395			    const __u16 (*sensormap)[2])
 396{
 397	while ((*sensormap)[0]) {
 398		gspca_dev->usb_buf[0] = (*sensormap)[1];
 399		gspca_dev->usb_buf[1] = (*sensormap)[1] >> 8;
 400		reg_w_buf(gspca_dev, (*sensormap)[0], 2);
 401		sensormap++;
 402	}
 403}
 404
 405static void write_sensor_72a(struct gspca_dev *gspca_dev,
 406			    const __u16 (*sensor)[2])
 407{
 408	while ((*sensor)[0]) {
 409		i2c_write(gspca_dev, (*sensor)[1], (*sensor)[0]);
 410		sensor++;
 411	}
 412}
 413
 414static void init_161rev12A(struct gspca_dev *gspca_dev)
 415{
 416	write_vector(gspca_dev, spca561_161rev12A_data1);
 417	sensor_mapwrite(gspca_dev, Pb100_1map8300);
 418/*fixme: should be in sd_start*/
 419	write_vector(gspca_dev, spca561_161rev12A_data2);
 420	sensor_mapwrite(gspca_dev, Pb100_2map8300);
 421}
 422
 423/* this function is called at probe time */
 424static int sd_config(struct gspca_dev *gspca_dev,
 425		     const struct usb_device_id *id)
 426{
 427	struct sd *sd = (struct sd *) gspca_dev;
 428	struct cam *cam;
 429	__u16 vendor, product;
 430	__u8 data1, data2;
 431
 432	/* Read frm global register the USB product and vendor IDs, just to
 433	 * prove that we can communicate with the device.  This works, which
 434	 * confirms at we are communicating properly and that the device
 435	 * is a 561. */
 436	reg_r(gspca_dev, 0x8104, 1);
 437	data1 = gspca_dev->usb_buf[0];
 438	reg_r(gspca_dev, 0x8105, 1);
 439	data2 = gspca_dev->usb_buf[0];
 440	vendor = (data2 << 8) | data1;
 441	reg_r(gspca_dev, 0x8106, 1);
 442	data1 = gspca_dev->usb_buf[0];
 443	reg_r(gspca_dev, 0x8107, 1);
 444	data2 = gspca_dev->usb_buf[0];
 445	product = (data2 << 8) | data1;
 446	if (vendor != id->idVendor || product != id->idProduct) {
 447		PDEBUG(D_PROBE, "Bad vendor / product from device");
 448		return -EINVAL;
 449	}
 450
 451	cam = &gspca_dev->cam;
 452	gspca_dev->nbalt = 7 + 1;	/* choose alternate 7 first */
 453
 454	sd->chip_revision = id->driver_info;
 455	if (sd->chip_revision == Rev012A) {
 456		cam->cam_mode = sif_012a_mode;
 457		cam->nmodes = ARRAY_SIZE(sif_012a_mode);
 458	} else {
 459		cam->cam_mode = sif_072a_mode;
 460		cam->nmodes = ARRAY_SIZE(sif_072a_mode);
 461	}
 462	sd->brightness = BRIGHTNESS_DEF;
 463	sd->contrast = CONTRAST_DEF;
 464	sd->white = HUE_DEF;
 465	sd->exposure = EXPOSURE_DEF;
 466	sd->autogain = AUTOGAIN_DEF;
 467	sd->gain = GAIN_DEF;
 468	sd->expo12a = EXPO12A_DEF;
 469	return 0;
 470}
 471
 472/* this function is called at probe and resume time */
 473static int sd_init_12a(struct gspca_dev *gspca_dev)
 474{
 475	PDEBUG(D_STREAM, "Chip revision: 012a");
 476	init_161rev12A(gspca_dev);
 477	return 0;
 478}
 479static int sd_init_72a(struct gspca_dev *gspca_dev)
 480{
 481	PDEBUG(D_STREAM, "Chip revision: 072a");
 482	write_vector(gspca_dev, rev72a_reset);
 483	msleep(200);
 484	write_vector(gspca_dev, rev72a_init_data1);
 485	write_sensor_72a(gspca_dev, rev72a_init_sensor1);
 486	write_vector(gspca_dev, rev72a_init_data2);
 487	write_sensor_72a(gspca_dev, rev72a_init_sensor2);
 488	reg_w_val(gspca_dev->dev, 0x8112, 0x30);
 489	return 0;
 490}
 491
 492/* rev 72a only */
 493static void setbrightness(struct gspca_dev *gspca_dev)
 494{
 495	struct sd *sd = (struct sd *) gspca_dev;
 496	struct usb_device *dev = gspca_dev->dev;
 497	__u8 value;
 498
 499	value = sd->brightness;
 500
 501	/* offsets for white balance */
 502	reg_w_val(dev, 0x8611, value);		/* R */
 503	reg_w_val(dev, 0x8612, value);		/* Gr */
 504	reg_w_val(dev, 0x8613, value);		/* B */
 505	reg_w_val(dev, 0x8614, value);		/* Gb */
 506}
 507
 508static void setwhite(struct gspca_dev *gspca_dev)
 509{
 510	struct sd *sd = (struct sd *) gspca_dev;
 511	__u16 white;
 512	__u8 blue, red;
 513	__u16 reg;
 514
 515	/* try to emulate MS-win as possible */
 516	white = sd->white;
 517	red = 0x20 + white * 3 / 8;
 518	blue = 0x90 - white * 5 / 8;
 519	if (sd->chip_revision == Rev012A) {
 520		reg = 0x8614;
 521	} else {
 522		reg = 0x8651;
 523		red += sd->contrast - 0x20;
 524		blue += sd->contrast - 0x20;
 525	}
 526	reg_w_val(gspca_dev->dev, reg, red);
 527	reg_w_val(gspca_dev->dev, reg + 2, blue);
 528}
 529
 530static void setcontrast(struct gspca_dev *gspca_dev)
 531{
 532	struct sd *sd = (struct sd *) gspca_dev;
 533	struct usb_device *dev = gspca_dev->dev;
 534	__u8 value;
 535
 536	if (sd->chip_revision != Rev072A)
 537		return;
 538	value = sd->contrast + 0x20;
 539
 540	/* gains for white balance */
 541	setwhite(gspca_dev);
 542/*	reg_w_val(dev, 0x8651, value);		 * R - done by setwhite */
 543	reg_w_val(dev, 0x8652, value);		/* Gr */
 544/*	reg_w_val(dev, 0x8653, value);		 * B - done by setwhite */
 545	reg_w_val(dev, 0x8654, value);		/* Gb */
 546}
 547
 548/* rev 12a only */
 549static void setexposure(struct gspca_dev *gspca_dev)
 550{
 551	struct sd *sd = (struct sd *) gspca_dev;
 552	int i, expo = 0;
 553
 554	/* Register 0x8309 controls exposure for the spca561,
 555	   the basic exposure setting goes from 1-2047, where 1 is completely
 556	   dark and 2047 is very bright. It not only influences exposure but
 557	   also the framerate (to allow for longer exposure) from 1 - 300 it
 558	   only raises the exposure time then from 300 - 600 it halves the
 559	   framerate to be able to further raise the exposure time and for every
 560	   300 more it halves the framerate again. This allows for a maximum
 561	   exposure time of circa 0.2 - 0.25 seconds (30 / (2000/3000) fps).
 562	   Sometimes this is not enough, the 1-2047 uses bits 0-10, bits 11-12
 563	   configure a divider for the base framerate which us used at the
 564	   exposure setting of 1-300. These bits configure the base framerate
 565	   according to the following formula: fps = 60 / (value + 2) */
 566
 567	/* We choose to use the high bits setting the fixed framerate divisor
 568	   asap, as setting high basic exposure setting without the fixed
 569	   divider in combination with high gains makes the cam stop */
 570	int table[] =  { 0, 450, 550, 625, EXPOSURE_MAX };
 571
 572	for (i = 0; i < ARRAY_SIZE(table) - 1; i++) {
 573		if (sd->exposure <= table[i + 1]) {
 574			expo  = sd->exposure - table[i];
 575			if (i)
 576				expo += 300;
 577			expo |= i << 11;
 578			break;
 579		}
 580	}
 581
 582	gspca_dev->usb_buf[0] = expo;
 583	gspca_dev->usb_buf[1] = expo >> 8;
 584	reg_w_buf(gspca_dev, 0x8309, 2);
 585}
 586
 587/* rev 12a only */
 588static void setgain(struct gspca_dev *gspca_dev)
 589{
 590	struct sd *sd = (struct sd *) gspca_dev;
 591
 592	/* gain reg low 6 bits  0-63 gain, bit 6 and 7, both double the
 593	   sensitivity when set, so 31 + one of them set == 63, and 15
 594	   with both of them set == 63 */
 595	if (sd->gain < 64)
 596		gspca_dev->usb_buf[0] = sd->gain;
 597	else if (sd->gain < 128)
 598		gspca_dev->usb_buf[0] = (sd->gain / 2) | 0x40;
 599	else
 600		gspca_dev->usb_buf[0] = (sd->gain / 4) | 0xc0;
 601
 602	gspca_dev->usb_buf[1] = 0;
 603	reg_w_buf(gspca_dev, 0x8335, 2);
 604}
 605
 606static void setautogain(struct gspca_dev *gspca_dev)
 607{
 608	struct sd *sd = (struct sd *) gspca_dev;
 609
 610	if (sd->autogain)
 611		sd->ag_cnt = AG_CNT_START;
 612	else
 613		sd->ag_cnt = -1;
 614}
 615
 616static int sd_start_12a(struct gspca_dev *gspca_dev)
 617{
 618	struct usb_device *dev = gspca_dev->dev;
 619	int mode;
 620	static const __u8 Reg8391[8] =
 621		{0x92, 0x30, 0x20, 0x00, 0x0c, 0x00, 0x00, 0x00};
 622
 623	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
 624	if (mode <= 1) {
 625		/* Use compression on 320x240 and above */
 626		reg_w_val(dev, 0x8500, 0x10 | mode);
 627	} else {
 628		/* I couldn't get the compression to work below 320x240
 629		 * Fortunately at these resolutions the bandwidth
 630		 * is sufficient to push raw frames at ~20fps */
 631		reg_w_val(dev, 0x8500, mode);
 632	}		/* -- qq@kuku.eu.org */
 633
 634	gspca_dev->usb_buf[0] = 0xaa;
 635	gspca_dev->usb_buf[1] = 0x00;
 636	reg_w_buf(gspca_dev, 0x8307, 2);
 637	/* clock - lower 0x8X values lead to fps > 30 */
 638	reg_w_val(gspca_dev->dev, 0x8700, 0x8a);
 639					/* 0x8f 0x85 0x27 clock */
 640	reg_w_val(gspca_dev->dev, 0x8112, 0x1e | 0x20);
 641	reg_w_val(gspca_dev->dev, 0x850b, 0x03);
 642	memcpy(gspca_dev->usb_buf, Reg8391, 8);
 643	reg_w_buf(gspca_dev, 0x8391, 8);
 644	reg_w_buf(gspca_dev, 0x8390, 8);
 645	setwhite(gspca_dev);
 646	setgain(gspca_dev);
 647	setexposure(gspca_dev);
 648
 649	/* Led ON (bit 3 -> 0 */
 650	reg_w_val(gspca_dev->dev, 0x8114, 0x00);
 651	return 0;
 652}
 653static int sd_start_72a(struct gspca_dev *gspca_dev)
 654{
 655	struct usb_device *dev = gspca_dev->dev;
 656	int Clck;
 657	int mode;
 658
 659	write_vector(gspca_dev, rev72a_reset);
 660	msleep(200);
 661	write_vector(gspca_dev, rev72a_init_data1);
 662	write_sensor_72a(gspca_dev, rev72a_init_sensor1);
 663
 664	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
 665	switch (mode) {
 666	default:
 667	case 0:
 668		Clck = 0x27;		/* ms-win 0x87 */
 669		break;
 670	case 1:
 671		Clck = 0x25;
 672		break;
 673	case 2:
 674		Clck = 0x22;
 675		break;
 676	case 3:
 677		Clck = 0x21;
 678		break;
 679	}
 680	reg_w_val(dev, 0x8700, Clck);	/* 0x27 clock */
 681	reg_w_val(dev, 0x8702, 0x81);
 682	reg_w_val(dev, 0x8500, mode);	/* mode */
 683	write_sensor_72a(gspca_dev, rev72a_init_sensor2);
 684	setcontrast(gspca_dev);
 685/*	setbrightness(gspca_dev);	 * fixme: bad values */
 686	setautogain(gspca_dev);
 687	reg_w_val(dev, 0x8112, 0x10 | 0x20);
 688	return 0;
 689}
 690
 691static void sd_stopN(struct gspca_dev *gspca_dev)
 692{
 693	struct sd *sd = (struct sd *) gspca_dev;
 694
 695	if (sd->chip_revision == Rev012A) {
 696		reg_w_val(gspca_dev->dev, 0x8112, 0x0e);
 697		/* Led Off (bit 3 -> 1 */
 698		reg_w_val(gspca_dev->dev, 0x8114, 0x08);
 699	} else {
 700		reg_w_val(gspca_dev->dev, 0x8112, 0x20);
 701/*		reg_w_val(gspca_dev->dev, 0x8102, 0x00); ?? */
 702	}
 703}
 704
 705static void do_autogain(struct gspca_dev *gspca_dev)
 706{
 707	struct sd *sd = (struct sd *) gspca_dev;
 708	int expotimes;
 709	int pixelclk;
 710	int gainG;
 711	__u8 R, Gr, Gb, B;
 712	int y;
 713	__u8 luma_mean = 110;
 714	__u8 luma_delta = 20;
 715	__u8 spring = 4;
 716
 717	if (sd->ag_cnt < 0)
 718		return;
 719	if (--sd->ag_cnt >= 0)
 720		return;
 721	sd->ag_cnt = AG_CNT_START;
 722
 723	switch (sd->chip_revision) {
 724	case Rev072A:
 725		reg_r(gspca_dev, 0x8621, 1);
 726		Gr = gspca_dev->usb_buf[0];
 727		reg_r(gspca_dev, 0x8622, 1);
 728		R = gspca_dev->usb_buf[0];
 729		reg_r(gspca_dev, 0x8623, 1);
 730		B = gspca_dev->usb_buf[0];
 731		reg_r(gspca_dev, 0x8624, 1);
 732		Gb = gspca_dev->usb_buf[0];
 733		y = (77 * R + 75 * (Gr + Gb) + 29 * B) >> 8;
 734		/* u= (128*B-(43*(Gr+Gb+R))) >> 8; */
 735		/* v= (128*R-(53*(Gr+Gb))-21*B) >> 8; */
 736		/* PDEBUG(D_CONF,"reading Y %d U %d V %d ",y,u,v); */
 737
 738		if (y < luma_mean - luma_delta ||
 739		    y > luma_mean + luma_delta) {
 740			expotimes = i2c_read(gspca_dev, 0x09, 0x10);
 741			pixelclk = 0x0800;
 742			expotimes = expotimes & 0x07ff;
 743			/* PDEBUG(D_PACK,
 744				"Exposition Times 0x%03X Clock 0x%04X ",
 745				expotimes,pixelclk); */
 746			gainG = i2c_read(gspca_dev, 0x35, 0x10);
 747			/* PDEBUG(D_PACK,
 748				"reading Gain register %d", gainG); */
 749
 750			expotimes += (luma_mean - y) >> spring;
 751			gainG += (luma_mean - y) / 50;
 752			/* PDEBUG(D_PACK,
 753				"compute expotimes %d gain %d",
 754				expotimes,gainG); */
 755
 756			if (gainG > 0x3f)
 757				gainG = 0x3f;
 758			else if (gainG < 3)
 759				gainG = 3;
 760			i2c_write(gspca_dev, gainG, 0x35);
 761
 762			if (expotimes > 0x0256)
 763				expotimes = 0x0256;
 764			else if (expotimes < 3)
 765				expotimes = 3;
 766			i2c_write(gspca_dev, expotimes | pixelclk, 0x09);
 767		}
 768		break;
 769	}
 770}
 771
 772static void sd_pkt_scan(struct gspca_dev *gspca_dev,
 773			u8 *data,		/* isoc packet */
 774			int len)		/* iso packet length */
 775{
 776	struct sd *sd = (struct sd *) gspca_dev;
 777
 778	len--;
 779	switch (*data++) {			/* sequence number */
 780	case 0:					/* start of frame */
 781		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
 782
 783		/* This should never happen */
 784		if (len < 2) {
 785			PDEBUG(D_ERR, "Short SOF packet, ignoring");
 786			gspca_dev->last_packet_type = DISCARD_PACKET;
 787			return;
 788		}
 789
 790#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
 791		if (data[0] & 0x20) {
 792			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
 793			input_sync(gspca_dev->input_dev);
 794			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
 795			input_sync(gspca_dev->input_dev);
 796		}
 797#endif
 798
 799		if (data[1] & 0x10) {
 800			/* compressed bayer */
 801			gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 802		} else {
 803			/* raw bayer (with a header, which we skip) */
 804			if (sd->chip_revision == Rev012A) {
 805				data += 20;
 806				len -= 20;
 807			} else {
 808				data += 16;
 809				len -= 16;
 810			}
 811			gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
 812		}
 813		return;
 814	case 0xff:			/* drop (empty mpackets) */
 815		return;
 816	}
 817	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 818}
 819
 820/* rev 72a only */
 821static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
 822{
 823	struct sd *sd = (struct sd *) gspca_dev;
 824
 825	sd->brightness = val;
 826	if (gspca_dev->streaming)
 827		setbrightness(gspca_dev);
 828	return 0;
 829}
 830
 831static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
 832{
 833	struct sd *sd = (struct sd *) gspca_dev;
 834
 835	*val = sd->brightness;
 836	return 0;
 837}
 838
 839/* rev 72a only */
 840static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
 841{
 842	struct sd *sd = (struct sd *) gspca_dev;
 843
 844	sd->contrast = val;
 845	if (gspca_dev->streaming)
 846		setcontrast(gspca_dev);
 847	return 0;
 848}
 849
 850static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
 851{
 852	struct sd *sd = (struct sd *) gspca_dev;
 853
 854	*val = sd->contrast;
 855	return 0;
 856}
 857
 858static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
 859{
 860	struct sd *sd = (struct sd *) gspca_dev;
 861
 862	sd->autogain = val;
 863	if (gspca_dev->streaming)
 864		setautogain(gspca_dev);
 865	return 0;
 866}
 867
 868static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
 869{
 870	struct sd *sd = (struct sd *) gspca_dev;
 871
 872	*val = sd->autogain;
 873	return 0;
 874}
 875
 876static int sd_setwhite(struct gspca_dev *gspca_dev, __s32 val)
 877{
 878	struct sd *sd = (struct sd *) gspca_dev;
 879
 880	sd->white = val;
 881	if (gspca_dev->streaming)
 882		setwhite(gspca_dev);
 883	return 0;
 884}
 885
 886static int sd_getwhite(struct gspca_dev *gspca_dev, __s32 *val)
 887{
 888	struct sd *sd = (struct sd *) gspca_dev;
 889
 890	*val = sd->white;
 891	return 0;
 892}
 893
 894/* rev12a only */
 895static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
 896{
 897	struct sd *sd = (struct sd *) gspca_dev;
 898
 899	sd->exposure = val;
 900	if (gspca_dev->streaming)
 901		setexposure(gspca_dev);
 902	return 0;
 903}
 904
 905static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
 906{
 907	struct sd *sd = (struct sd *) gspca_dev;
 908
 909	*val = sd->exposure;
 910	return 0;
 911}
 912
 913/* rev12a only */
 914static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
 915{
 916	struct sd *sd = (struct sd *) gspca_dev;
 917
 918	sd->gain = val;
 919	if (gspca_dev->streaming)
 920		setgain(gspca_dev);
 921	return 0;
 922}
 923
 924static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
 925{
 926	struct sd *sd = (struct sd *) gspca_dev;
 927
 928	*val = sd->gain;
 929	return 0;
 930}
 931
 932/* control tables */
 933static const struct ctrl sd_ctrls_12a[] = {
 934	{
 935	    {
 936		.id = V4L2_CID_HUE,
 937		.type = V4L2_CTRL_TYPE_INTEGER,
 938		.name = "Hue",
 939		.minimum = HUE_MIN,
 940		.maximum = HUE_MAX,
 941		.step = 1,
 942		.default_value = HUE_DEF,
 943	    },
 944	    .set = sd_setwhite,
 945	    .get = sd_getwhite,
 946	},
 947	{
 948	    {
 949		.id = V4L2_CID_EXPOSURE,
 950		.type = V4L2_CTRL_TYPE_INTEGER,
 951		.name = "Exposure",
 952		.minimum = EXPOSURE_MIN,
 953		.maximum = EXPOSURE_MAX,
 954		.step = 1,
 955		.default_value = EXPOSURE_DEF,
 956	    },
 957	    .set = sd_setexposure,
 958	    .get = sd_getexposure,
 959	},
 960	{
 961	    {
 962		.id = V4L2_CID_GAIN,
 963		.type = V4L2_CTRL_TYPE_INTEGER,
 964		.name = "Gain",
 965		.minimum = GAIN_MIN,
 966		.maximum = GAIN_MAX,
 967		.step = 1,
 968		.default_value = GAIN_DEF,
 969	    },
 970	    .set = sd_setgain,
 971	    .get = sd_getgain,
 972	},
 973};
 974
 975static const struct ctrl sd_ctrls_72a[] = {
 976	{
 977	    {
 978		.id = V4L2_CID_HUE,
 979		.type = V4L2_CTRL_TYPE_INTEGER,
 980		.name = "Hue",
 981		.minimum = HUE_MIN,
 982		.maximum = HUE_MAX,
 983		.step = 1,
 984		.default_value = HUE_DEF,
 985	    },
 986	    .set = sd_setwhite,
 987	    .get = sd_getwhite,
 988	},
 989	{
 990	   {
 991		.id = V4L2_CID_BRIGHTNESS,
 992		.type = V4L2_CTRL_TYPE_INTEGER,
 993		.name = "Brightness",
 994		.minimum = BRIGHTNESS_MIN,
 995		.maximum = BRIGHTNESS_MAX,
 996		.step = 1,
 997		.default_value = BRIGHTNESS_DEF,
 998	    },
 999	    .set = sd_setbrightness,
1000	    .get = sd_getbrightness,
1001	},
1002	{
1003	    {
1004		.id = V4L2_CID_CONTRAST,
1005		.type = V4L2_CTRL_TYPE_INTEGER,
1006		.name = "Contrast",
1007		.minimum = CONTRAST_MIN,
1008		.maximum = CONTRAST_MAX,
1009		.step = 1,
1010		.default_value = CONTRAST_DEF,
1011	    },
1012	    .set = sd_setcontrast,
1013	    .get = sd_getcontrast,
1014	},
1015	{
1016	    {
1017		.id = V4L2_CID_AUTOGAIN,
1018		.type = V4L2_CTRL_TYPE_BOOLEAN,
1019		.name = "Auto Gain",
1020		.minimum = AUTOGAIN_MIN,
1021		.maximum = AUTOGAIN_MAX,
1022		.step = 1,
1023		.default_value = AUTOGAIN_DEF,
1024	    },
1025	    .set = sd_setautogain,
1026	    .get = sd_getautogain,
1027	},
1028};
1029
1030/* sub-driver description */
1031static const struct sd_desc sd_desc_12a = {
1032	.name = MODULE_NAME,
1033	.ctrls = sd_ctrls_12a,
1034	.nctrls = ARRAY_SIZE(sd_ctrls_12a),
1035	.config = sd_config,
1036	.init = sd_init_12a,
1037	.start = sd_start_12a,
1038	.stopN = sd_stopN,
1039	.pkt_scan = sd_pkt_scan,
1040#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1041	.other_input = 1,
1042#endif
1043};
1044static const struct sd_desc sd_desc_72a = {
1045	.name = MODULE_NAME,
1046	.ctrls = sd_ctrls_72a,
1047	.nctrls = ARRAY_SIZE(sd_ctrls_72a),
1048	.config = sd_config,
1049	.init = sd_init_72a,
1050	.start = sd_start_72a,
1051	.stopN = sd_stopN,
1052	.pkt_scan = sd_pkt_scan,
1053	.dq_callback = do_autogain,
1054#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1055	.other_input = 1,
1056#endif
1057};
1058static const struct sd_desc *sd_desc[2] = {
1059	&sd_desc_12a,
1060	&sd_desc_72a
1061};
1062
1063/* -- module initialisation -- */
1064static const struct usb_device_id device_table[] = {
1065	{USB_DEVICE(0x041e, 0x401a), .driver_info = Rev072A},
1066	{USB_DEVICE(0x041e, 0x403b), .driver_info = Rev012A},
1067	{USB_DEVICE(0x0458, 0x7004), .driver_info = Rev072A},
1068	{USB_DEVICE(0x0461, 0x0815), .driver_info = Rev072A},
1069	{USB_DEVICE(0x046d, 0x0928), .driver_info = Rev012A},
1070	{USB_DEVICE(0x046d, 0x0929), .driver_info = Rev012A},
1071	{USB_DEVICE(0x046d, 0x092a), .driver_info = Rev012A},
1072	{USB_DEVICE(0x046d, 0x092b), .driver_info = Rev012A},
1073	{USB_DEVICE(0x046d, 0x092c), .driver_info = Rev012A},
1074	{USB_DEVICE(0x046d, 0x092d), .driver_info = Rev012A},
1075	{USB_DEVICE(0x046d, 0x092e), .driver_info = Rev012A},
1076	{USB_DEVICE(0x046d, 0x092f), .driver_info = Rev012A},
1077	{USB_DEVICE(0x04fc, 0x0561), .driver_info = Rev072A},
1078	{USB_DEVICE(0x060b, 0xa001), .driver_info = Rev072A},
1079	{USB_DEVICE(0x10fd, 0x7e50), .driver_info = Rev072A},
1080	{USB_DEVICE(0xabcd, 0xcdee), .driver_info = Rev072A},
1081	{}
1082};
1083
1084MODULE_DEVICE_TABLE(usb, device_table);
1085
1086/* -- device connect -- */
1087static int sd_probe(struct usb_interface *intf,
1088		    const struct usb_device_id *id)
1089{
1090	return gspca_dev_probe(intf, id,
1091				sd_desc[id->driver_info],
1092				sizeof(struct sd),
1093			       THIS_MODULE);
1094}
1095
1096static struct usb_driver sd_driver = {
1097	.name = MODULE_NAME,
1098	.id_table = device_table,
1099	.probe = sd_probe,
1100	.disconnect = gspca_disconnect,
1101#ifdef CONFIG_PM
1102	.suspend = gspca_suspend,
1103	.resume = gspca_resume,
1104#endif
1105};
1106
1107/* -- module insert / remove -- */
1108static int __init sd_mod_init(void)
1109{
1110	return usb_register(&sd_driver);
1111}
1112static void __exit sd_mod_exit(void)
1113{
1114	usb_deregister(&sd_driver);
1115}
1116
1117module_init(sd_mod_init);
1118module_exit(sd_mod_exit);