sn9c20x.c 69.4 KB
Newer Older
1 2
/*
 *	Sonix sn9c201 sn9c202 library
3 4
 *
 * Copyright (C) 2012 Jean-Francois Moine <http://moinejf.free.fr>
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *	Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com>
 *	Copyright (C) 2009 Brian Johnson <brijohn@gmail.com>
 *
 * 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
 */

23 24
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

25 26
#include <linux/input.h>

27 28 29 30
#include "gspca.h"
#include "jpeg.h"

#include <media/v4l2-chip-ident.h>
31
#include <linux/dmi.h>
32

33 34 35 36 37
MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, "
		"microdia project <microdia@googlegroups.com>");
MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
MODULE_LICENSE("GPL");

38 39 40 41 42 43 44 45
/*
 * Pixel format private data
 */
#define SCALE_MASK	0x0f
#define SCALE_160x120	0
#define SCALE_320x240	1
#define SCALE_640x480	2
#define SCALE_1280x1024	3
46 47 48 49 50 51 52 53 54 55 56 57 58 59
#define MODE_RAW	0x10
#define MODE_JPEG	0x20
#define MODE_SXGA	0x80

#define SENSOR_OV9650	0
#define SENSOR_OV9655	1
#define SENSOR_SOI968	2
#define SENSOR_OV7660	3
#define SENSOR_OV7670	4
#define SENSOR_MT9V011	5
#define SENSOR_MT9V111	6
#define SENSOR_MT9V112	7
#define SENSOR_MT9M001	8
#define SENSOR_MT9M111	9
60 61
#define SENSOR_MT9M112  10
#define SENSOR_HV7131R	11
62
#define SENSOR_MT9VPRB	12
63

64
/* camera flags */
65
#define HAS_NO_BUTTON	0x1
66
#define LED_REVERSE	0x2 /* some cameras unset gpio to turn on leds */
67
#define FLIP_DETECT	0x4
68

69 70 71 72 73 74 75 76 77 78 79 80 81
enum e_ctrl {
	BRIGHTNESS,
	CONTRAST,
	SATURATION,
	HUE,
	GAMMA,
	BLUE,
	RED,
	VFLIP,
	HFLIP,
	EXPOSURE,
	GAIN,
	AUTOGAIN,
82
	QUALITY,
83 84 85
	NCTRLS		/* number of controls */
};

86 87 88 89
/* specific webcam descriptor */
struct sd {
	struct gspca_dev gspca_dev;

90 91
	struct gspca_ctrl ctrls[NCTRLS];

92 93 94 95 96 97
	struct work_struct work;
	struct workqueue_struct *work_thread;

	u32 pktsz;			/* (used by pkt_scan) */
	u16 npkt;
	s8 nchg;
98 99
	u8 fmt;				/* (used for JPEG QTAB update */

100 101 102 103 104 105 106 107 108 109 110 111
#define MIN_AVG_LUM 80
#define MAX_AVG_LUM 130
	atomic_t avg_lum;
	u8 old_step;
	u8 older_step;
	u8 exposure_step;

	u8 i2c_addr;
	u8 sensor;
	u8 hstart;
	u8 vstart;

112
	u8 jpeg_hdr[JPEG_HDR_SZ];
113

114
	u8 flags;
115 116
};

117 118
static void qual_upd(struct work_struct *work);

119 120 121 122 123 124 125 126 127 128
struct i2c_reg_u8 {
	u8 reg;
	u8 val;
};

struct i2c_reg_u16 {
	u8 reg;
	u16 val;
};

129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
static const struct dmi_system_id flip_dmi_table[] = {
	{
		.ident = "MSI MS-1034",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
			DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
			DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
		}
	},
	{
		.ident = "MSI MS-1632",
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
			DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
		}
	},
145 146 147 148 149 150 151
	{
		.ident = "MSI MS-1633X",
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
			DMI_MATCH(DMI_BOARD_NAME, "MS-1633X")
		}
	},
152 153 154 155 156 157 158
	{
		.ident = "MSI MS-1635X",
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
			DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
		}
	},
159 160 161 162 163 164 165
	{
		.ident = "ASUSTeK W7J",
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
			DMI_MATCH(DMI_BOARD_NAME, "W7J       ")
		}
	},
166 167 168
	{}
};

169 170 171 172 173 174
static void set_cmatrix(struct gspca_dev *gspca_dev);
static void set_gamma(struct gspca_dev *gspca_dev);
static void set_redblue(struct gspca_dev *gspca_dev);
static void set_hvflip(struct gspca_dev *gspca_dev);
static void set_exposure(struct gspca_dev *gspca_dev);
static void set_gain(struct gspca_dev *gspca_dev);
175
static void set_quality(struct gspca_dev *gspca_dev);
176 177 178

static const struct ctrl sd_ctrls[NCTRLS] = {
[BRIGHTNESS] = {
179 180 181 182 183 184 185
	    {
		.id      = V4L2_CID_BRIGHTNESS,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Brightness",
		.minimum = 0,
		.maximum = 0xff,
		.step    = 1,
186
		.default_value = 0x7f
187
	    },
188
	    .set_control = set_cmatrix
189
	},
190
[CONTRAST] = {
191 192 193 194 195 196 197
	    {
		.id      = V4L2_CID_CONTRAST,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Contrast",
		.minimum = 0,
		.maximum = 0xff,
		.step    = 1,
198
		.default_value = 0x7f
199
	    },
200
	    .set_control = set_cmatrix
201
	},
202
[SATURATION] = {
203 204 205 206 207 208 209
	    {
		.id      = V4L2_CID_SATURATION,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Saturation",
		.minimum = 0,
		.maximum = 0xff,
		.step    = 1,
210
		.default_value = 0x7f
211
	    },
212
	    .set_control = set_cmatrix
213
	},
214
[HUE] = {
215 216 217 218 219 220 221
	    {
		.id      = V4L2_CID_HUE,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Hue",
		.minimum = -180,
		.maximum = 180,
		.step    = 1,
222
		.default_value = 0
223
	    },
224
	    .set_control = set_cmatrix
225
	},
226
[GAMMA] = {
227 228 229 230 231 232 233
	    {
		.id      = V4L2_CID_GAMMA,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Gamma",
		.minimum = 0,
		.maximum = 0xff,
		.step    = 1,
234
		.default_value = 0x10
235
	    },
236
	    .set_control = set_gamma
237
	},
238
[BLUE] = {
239 240 241 242 243 244 245
	    {
		.id	 = V4L2_CID_BLUE_BALANCE,
		.type	 = V4L2_CTRL_TYPE_INTEGER,
		.name	 = "Blue Balance",
		.minimum = 0,
		.maximum = 0x7f,
		.step	 = 1,
246
		.default_value = 0x28
247
	    },
248
	    .set_control = set_redblue
249
	},
250
[RED] = {
251 252 253 254 255 256 257
	    {
		.id	 = V4L2_CID_RED_BALANCE,
		.type	 = V4L2_CTRL_TYPE_INTEGER,
		.name	 = "Red Balance",
		.minimum = 0,
		.maximum = 0x7f,
		.step	 = 1,
258
		.default_value = 0x28
259
	    },
260
	    .set_control = set_redblue
261
	},
262
[HFLIP] = {
263 264 265 266 267 268 269
	    {
		.id      = V4L2_CID_HFLIP,
		.type    = V4L2_CTRL_TYPE_BOOLEAN,
		.name    = "Horizontal Flip",
		.minimum = 0,
		.maximum = 1,
		.step    = 1,
270
		.default_value = 0,
271
	    },
272
	    .set_control = set_hvflip
273
	},
274
[VFLIP] = {
275 276 277 278 279 280 281
	    {
		.id      = V4L2_CID_VFLIP,
		.type    = V4L2_CTRL_TYPE_BOOLEAN,
		.name    = "Vertical Flip",
		.minimum = 0,
		.maximum = 1,
		.step    = 1,
282
		.default_value = 0,
283
	    },
284
	    .set_control = set_hvflip
285
	},
286
[EXPOSURE] = {
287 288 289 290 291 292 293
	    {
		.id      = V4L2_CID_EXPOSURE,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Exposure",
		.minimum = 0,
		.maximum = 0x1780,
		.step    = 1,
294
		.default_value = 0x33,
295
	    },
296
	    .set_control = set_exposure
297
	},
298
[GAIN] = {
299 300 301 302 303 304 305
	    {
		.id      = V4L2_CID_GAIN,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Gain",
		.minimum = 0,
		.maximum = 28,
		.step    = 1,
306
		.default_value = 0,
307
	    },
308
	    .set_control = set_gain
309
	},
310
[AUTOGAIN] = {
311 312 313 314 315 316 317
	    {
		.id      = V4L2_CID_AUTOGAIN,
		.type    = V4L2_CTRL_TYPE_BOOLEAN,
		.name    = "Auto Exposure",
		.minimum = 0,
		.maximum = 1,
		.step    = 1,
318
		.default_value = 1,
319 320
	    },
	},
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
[QUALITY] = {
	    {
		.id      = V4L2_CID_JPEG_COMPRESSION_QUALITY,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Compression Quality",
#define QUALITY_MIN 50
#define QUALITY_MAX 90
#define QUALITY_DEF 80
		.minimum = QUALITY_MIN,
		.maximum = QUALITY_MAX,
		.step    = 1,
		.default_value = QUALITY_DEF,
	    },
	    .set_control = set_quality
	},
336 337 338 339
};

static const struct v4l2_pix_format vga_mode[] = {
	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
340
		.bytesperline = 160,
341
		.sizeimage = 160 * 120 * 4 / 8 + 590,
342
		.colorspace = V4L2_COLORSPACE_JPEG,
343
		.priv = SCALE_160x120 | MODE_JPEG},
344 345 346 347
	{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
		.bytesperline = 160,
		.sizeimage = 160 * 120,
		.colorspace = V4L2_COLORSPACE_SRGB,
348
		.priv = SCALE_160x120 | MODE_RAW},
349
	{160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
350
		.bytesperline = 160,
351 352
		.sizeimage = 240 * 120,
		.colorspace = V4L2_COLORSPACE_SRGB,
353
		.priv = SCALE_160x120},
354
	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
355
		.bytesperline = 320,
356
		.sizeimage = 320 * 240 * 4 / 8 + 590,
357
		.colorspace = V4L2_COLORSPACE_JPEG,
358
		.priv = SCALE_320x240 | MODE_JPEG},
359 360 361 362
	{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
		.bytesperline = 320,
		.sizeimage = 320 * 240 ,
		.colorspace = V4L2_COLORSPACE_SRGB,
363
		.priv = SCALE_320x240 | MODE_RAW},
364
	{320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
365
		.bytesperline = 320,
366 367
		.sizeimage = 480 * 240 ,
		.colorspace = V4L2_COLORSPACE_SRGB,
368
		.priv = SCALE_320x240},
369
	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
370
		.bytesperline = 640,
371
		.sizeimage = 640 * 480 * 4 / 8 + 590,
372
		.colorspace = V4L2_COLORSPACE_JPEG,
373
		.priv = SCALE_640x480 | MODE_JPEG},
374 375 376 377
	{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
		.bytesperline = 640,
		.sizeimage = 640 * 480,
		.colorspace = V4L2_COLORSPACE_SRGB,
378
		.priv = SCALE_640x480 | MODE_RAW},
379
	{640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
380
		.bytesperline = 640,
381 382
		.sizeimage = 960 * 480,
		.colorspace = V4L2_COLORSPACE_SRGB,
383
		.priv = SCALE_640x480},
384 385 386 387
};

static const struct v4l2_pix_format sxga_mode[] = {
	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
388
		.bytesperline = 160,
389
		.sizeimage = 160 * 120 * 4 / 8 + 590,
390
		.colorspace = V4L2_COLORSPACE_JPEG,
391
		.priv = SCALE_160x120 | MODE_JPEG},
392 393 394 395
	{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
		.bytesperline = 160,
		.sizeimage = 160 * 120,
		.colorspace = V4L2_COLORSPACE_SRGB,
396
		.priv = SCALE_160x120 | MODE_RAW},
397
	{160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
398
		.bytesperline = 160,
399 400
		.sizeimage = 240 * 120,
		.colorspace = V4L2_COLORSPACE_SRGB,
401
		.priv = SCALE_160x120},
402
	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
403
		.bytesperline = 320,
404
		.sizeimage = 320 * 240 * 4 / 8 + 590,
405
		.colorspace = V4L2_COLORSPACE_JPEG,
406
		.priv = SCALE_320x240 | MODE_JPEG},
407 408 409 410
	{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
		.bytesperline = 320,
		.sizeimage = 320 * 240 ,
		.colorspace = V4L2_COLORSPACE_SRGB,
411
		.priv = SCALE_320x240 | MODE_RAW},
412
	{320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
413
		.bytesperline = 320,
414 415
		.sizeimage = 480 * 240 ,
		.colorspace = V4L2_COLORSPACE_SRGB,
416
		.priv = SCALE_320x240},
417
	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
418
		.bytesperline = 640,
419
		.sizeimage = 640 * 480 * 4 / 8 + 590,
420
		.colorspace = V4L2_COLORSPACE_JPEG,
421
		.priv = SCALE_640x480 | MODE_JPEG},
422 423 424 425
	{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
		.bytesperline = 640,
		.sizeimage = 640 * 480,
		.colorspace = V4L2_COLORSPACE_SRGB,
426
		.priv = SCALE_640x480 | MODE_RAW},
427
	{640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
428
		.bytesperline = 640,
429 430
		.sizeimage = 960 * 480,
		.colorspace = V4L2_COLORSPACE_SRGB,
431
		.priv = SCALE_640x480},
432 433
	{1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
		.bytesperline = 1280,
434
		.sizeimage = 1280 * 1024,
435
		.colorspace = V4L2_COLORSPACE_SRGB,
436
		.priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
437 438
};

439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
static const struct v4l2_pix_format mono_mode[] = {
	{160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
		.bytesperline = 160,
		.sizeimage = 160 * 120,
		.colorspace = V4L2_COLORSPACE_SRGB,
		.priv = SCALE_160x120 | MODE_RAW},
	{320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
		.bytesperline = 320,
		.sizeimage = 320 * 240 ,
		.colorspace = V4L2_COLORSPACE_SRGB,
		.priv = SCALE_320x240 | MODE_RAW},
	{640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
		.bytesperline = 640,
		.sizeimage = 640 * 480,
		.colorspace = V4L2_COLORSPACE_SRGB,
		.priv = SCALE_640x480 | MODE_RAW},
	{1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
		.bytesperline = 1280,
		.sizeimage = 1280 * 1024,
		.colorspace = V4L2_COLORSPACE_SRGB,
		.priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
};

462
static const s16 hsv_red_x[] = {
463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
	41,  44,  46,  48,  50,  52,  54,  56,
	58,  60,  62,  64,  66,  68,  70,  72,
	74,  76,  78,  80,  81,  83,  85,  87,
	88,  90,  92,  93,  95,  97,  98, 100,
	101, 102, 104, 105, 107, 108, 109, 110,
	112, 113, 114, 115, 116, 117, 118, 119,
	120, 121, 122, 123, 123, 124, 125, 125,
	126, 127, 127, 128, 128, 129, 129, 129,
	130, 130, 130, 130, 131, 131, 131, 131,
	131, 131, 131, 131, 130, 130, 130, 130,
	129, 129, 129, 128, 128, 127, 127, 126,
	125, 125, 124, 123, 122, 122, 121, 120,
	119, 118, 117, 116, 115, 114, 112, 111,
	110, 109, 107, 106, 105, 103, 102, 101,
	99,  98,  96,  94,  93,  91,  90,  88,
	86,  84,  83,  81,  79,  77,  75,  74,
	72,  70,  68,  66,  64,  62,  60,  58,
	56,  54,  52,  49,  47,  45,  43,  41,
	39,  36,  34,  32,  30,  28,  25,  23,
	21,  19,  16,  14,  12,   9,   7,   5,
	3,   0,  -1,  -3,  -6,  -8, -10, -12,
	-15, -17, -19, -22, -24, -26, -28, -30,
	-33, -35, -37, -39, -41, -44, -46, -48,
	-50, -52, -54, -56, -58, -60, -62, -64,
	-66, -68, -70, -72, -74, -76, -78, -80,
	-81, -83, -85, -87, -88, -90, -92, -93,
	-95, -97, -98, -100, -101, -102, -104, -105,
	-107, -108, -109, -110, -112, -113, -114, -115,
	-116, -117, -118, -119, -120, -121, -122, -123,
	-123, -124, -125, -125, -126, -127, -127, -128,
	-128, -128, -128, -128, -128, -128, -128, -128,
	-128, -128, -128, -128, -128, -128, -128, -128,
	-128, -128, -128, -128, -128, -128, -128, -128,
	-128, -127, -127, -126, -125, -125, -124, -123,
	-122, -122, -121, -120, -119, -118, -117, -116,
	-115, -114, -112, -111, -110, -109, -107, -106,
	-105, -103, -102, -101, -99, -98, -96, -94,
	-93, -91, -90, -88, -86, -84, -83, -81,
	-79, -77, -75, -74, -72, -70, -68, -66,
	-64, -62, -60, -58, -56, -54, -52, -49,
	-47, -45, -43, -41, -39, -36, -34, -32,
	-30, -28, -25, -23, -21, -19, -16, -14,
	-12,  -9,  -7,  -5,  -3,   0,   1,   3,
	6,   8,  10,  12,  15,  17,  19,  22,
	24,  26,  28,  30,  33,  35,  37,  39, 41
};

510
static const s16 hsv_red_y[] = {
511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
	82,  80,  78,  76,  74,  73,  71,  69,
	67,  65,  63,  61,  58,  56,  54,  52,
	50,  48,  46,  44,  41,  39,  37,  35,
	32,  30,  28,  26,  23,  21,  19,  16,
	14,  12,  10,   7,   5,   3,   0,  -1,
	-3,  -6,  -8, -10, -13, -15, -17, -19,
	-22, -24, -26, -29, -31, -33, -35, -38,
	-40, -42, -44, -46, -48, -51, -53, -55,
	-57, -59, -61, -63, -65, -67, -69, -71,
	-73, -75, -77, -79, -81, -82, -84, -86,
	-88, -89, -91, -93, -94, -96, -98, -99,
	-101, -102, -104, -105, -106, -108, -109, -110,
	-112, -113, -114, -115, -116, -117, -119, -120,
	-120, -121, -122, -123, -124, -125, -126, -126,
	-127, -128, -128, -128, -128, -128, -128, -128,
	-128, -128, -128, -128, -128, -128, -128, -128,
	-128, -128, -128, -128, -128, -128, -128, -128,
	-128, -128, -128, -128, -128, -128, -128, -128,
	-127, -127, -126, -125, -125, -124, -123, -122,
	-121, -120, -119, -118, -117, -116, -115, -114,
	-113, -111, -110, -109, -107, -106, -105, -103,
	-102, -100, -99, -97, -96, -94, -92, -91,
	-89, -87, -85, -84, -82, -80, -78, -76,
	-74, -73, -71, -69, -67, -65, -63, -61,
	-58, -56, -54, -52, -50, -48, -46, -44,
	-41, -39, -37, -35, -32, -30, -28, -26,
	-23, -21, -19, -16, -14, -12, -10,  -7,
	-5,  -3,   0,   1,   3,   6,   8,  10,
	13,  15,  17,  19,  22,  24,  26,  29,
	31,  33,  35,  38,  40,  42,  44,  46,
	48,  51,  53,  55,  57,  59,  61,  63,
	65,  67,  69,  71,  73,  75,  77,  79,
	81,  82,  84,  86,  88,  89,  91,  93,
	94,  96,  98,  99, 101, 102, 104, 105,
	106, 108, 109, 110, 112, 113, 114, 115,
	116, 117, 119, 120, 120, 121, 122, 123,
	124, 125, 126, 126, 127, 128, 128, 129,
	129, 130, 130, 131, 131, 131, 131, 132,
	132, 132, 132, 132, 132, 132, 132, 132,
	132, 132, 132, 131, 131, 131, 130, 130,
	130, 129, 129, 128, 127, 127, 126, 125,
	125, 124, 123, 122, 121, 120, 119, 118,
	117, 116, 115, 114, 113, 111, 110, 109,
	107, 106, 105, 103, 102, 100,  99,  97,
	96, 94, 92, 91, 89, 87, 85, 84, 82
};

558
static const s16 hsv_green_x[] = {
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605
	-124, -124, -125, -125, -125, -125, -125, -125,
	-125, -126, -126, -125, -125, -125, -125, -125,
	-125, -124, -124, -124, -123, -123, -122, -122,
	-121, -121, -120, -120, -119, -118, -117, -117,
	-116, -115, -114, -113, -112, -111, -110, -109,
	-108, -107, -105, -104, -103, -102, -100, -99,
	-98, -96, -95, -93, -92, -91, -89, -87,
	-86, -84, -83, -81, -79, -77, -76, -74,
	-72, -70, -69, -67, -65, -63, -61, -59,
	-57, -55, -53, -51, -49, -47, -45, -43,
	-41, -39, -37, -35, -33, -30, -28, -26,
	-24, -22, -20, -18, -15, -13, -11,  -9,
	-7,  -4,  -2,   0,   1,   3,   6,   8,
	10,  12,  14,  17,  19,  21,  23,  25,
	27,  29,  32,  34,  36,  38,  40,  42,
	44,  46,  48,  50,  52,  54,  56,  58,
	60,  62,  64,  66,  68,  70,  71,  73,
	75,  77,  78,  80,  82,  83,  85,  87,
	88,  90,  91,  93,  94,  96,  97,  98,
	100, 101, 102, 104, 105, 106, 107, 108,
	109, 111, 112, 113, 113, 114, 115, 116,
	117, 118, 118, 119, 120, 120, 121, 122,
	122, 123, 123, 124, 124, 124, 125, 125,
	125, 125, 125, 125, 125, 126, 126, 125,
	125, 125, 125, 125, 125, 124, 124, 124,
	123, 123, 122, 122, 121, 121, 120, 120,
	119, 118, 117, 117, 116, 115, 114, 113,
	112, 111, 110, 109, 108, 107, 105, 104,
	103, 102, 100,  99,  98,  96,  95,  93,
	92,  91,  89,  87,  86,  84,  83,  81,
	79,  77,  76,  74,  72,  70,  69,  67,
	65,  63,  61,  59,  57,  55,  53,  51,
	49,  47,  45,  43,  41,  39,  37,  35,
	33,  30,  28,  26,  24,  22,  20,  18,
	15,  13,  11,   9,   7,   4,   2,   0,
	-1,  -3,  -6,  -8, -10, -12, -14, -17,
	-19, -21, -23, -25, -27, -29, -32, -34,
	-36, -38, -40, -42, -44, -46, -48, -50,
	-52, -54, -56, -58, -60, -62, -64, -66,
	-68, -70, -71, -73, -75, -77, -78, -80,
	-82, -83, -85, -87, -88, -90, -91, -93,
	-94, -96, -97, -98, -100, -101, -102, -104,
	-105, -106, -107, -108, -109, -111, -112, -113,
	-113, -114, -115, -116, -117, -118, -118, -119,
	-120, -120, -121, -122, -122, -123, -123, -124, -124
};

606
static const s16 hsv_green_y[] = {
607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
	-100, -99, -98, -97, -95, -94, -93, -91,
	-90, -89, -87, -86, -84, -83, -81, -80,
	-78, -76, -75, -73, -71, -70, -68, -66,
	-64, -63, -61, -59, -57, -55, -53, -51,
	-49, -48, -46, -44, -42, -40, -38, -36,
	-34, -32, -30, -27, -25, -23, -21, -19,
	-17, -15, -13, -11,  -9,  -7,  -4,  -2,
	0,   1,   3,   5,   7,   9,  11,  14,
	16,  18,  20,  22,  24,  26,  28,  30,
	32,  34,  36,  38,  40,  42,  44,  46,
	48,  50,  52,  54,  56,  58,  59,  61,
	63,  65,  67,  68,  70,  72,  74,  75,
	77,  78,  80,  82,  83,  85,  86,  88,
	89,  90,  92,  93,  95,  96,  97,  98,
	100, 101, 102, 103, 104, 105, 106, 107,
	108, 109, 110, 111, 112, 112, 113, 114,
	115, 115, 116, 116, 117, 117, 118, 118,
	119, 119, 119, 120, 120, 120, 120, 120,
	121, 121, 121, 121, 121, 121, 120, 120,
	120, 120, 120, 119, 119, 119, 118, 118,
	117, 117, 116, 116, 115, 114, 114, 113,
	112, 111, 111, 110, 109, 108, 107, 106,
	105, 104, 103, 102, 100,  99,  98,  97,
	95,  94,  93,  91,  90,  89,  87,  86,
	84,  83,  81,  80,  78,  76,  75,  73,
	71,  70,  68,  66,  64,  63,  61,  59,
	57,  55,  53,  51,  49,  48,  46,  44,
	42,  40,  38,  36,  34,  32,  30,  27,
	25,  23,  21,  19,  17,  15,  13,  11,
	9,   7,   4,   2,   0,  -1,  -3,  -5,
	-7,  -9, -11, -14, -16, -18, -20, -22,
	-24, -26, -28, -30, -32, -34, -36, -38,
	-40, -42, -44, -46, -48, -50, -52, -54,
	-56, -58, -59, -61, -63, -65, -67, -68,
	-70, -72, -74, -75, -77, -78, -80, -82,
	-83, -85, -86, -88, -89, -90, -92, -93,
	-95, -96, -97, -98, -100, -101, -102, -103,
	-104, -105, -106, -107, -108, -109, -110, -111,
	-112, -112, -113, -114, -115, -115, -116, -116,
	-117, -117, -118, -118, -119, -119, -119, -120,
	-120, -120, -120, -120, -121, -121, -121, -121,
	-121, -121, -120, -120, -120, -120, -120, -119,
	-119, -119, -118, -118, -117, -117, -116, -116,
	-115, -114, -114, -113, -112, -111, -111, -110,
	-109, -108, -107, -106, -105, -104, -103, -102, -100
};

654
static const s16 hsv_blue_x[] = {
655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701
	112, 113, 114, 114, 115, 116, 117, 117,
	118, 118, 119, 119, 120, 120, 120, 121,
	121, 121, 122, 122, 122, 122, 122, 122,
	122, 122, 122, 122, 122, 122, 121, 121,
	121, 120, 120, 120, 119, 119, 118, 118,
	117, 116, 116, 115, 114, 113, 113, 112,
	111, 110, 109, 108, 107, 106, 105, 104,
	103, 102, 100,  99,  98,  97,  95,  94,
	93,  91,  90,  88,  87,  85,  84,  82,
	80,  79,  77,  76,  74,  72,  70,  69,
	67,  65,  63,  61,  60,  58,  56,  54,
	52,  50,  48,  46,  44,  42,  40,  38,
	36,  34,  32,  30,  28,  26,  24,  22,
	19,  17,  15,  13,  11,   9,   7,   5,
	2,   0,  -1,  -3,  -5,  -7,  -9, -12,
	-14, -16, -18, -20, -22, -24, -26, -28,
	-31, -33, -35, -37, -39, -41, -43, -45,
	-47, -49, -51, -53, -54, -56, -58, -60,
	-62, -64, -66, -67, -69, -71, -73, -74,
	-76, -78, -79, -81, -83, -84, -86, -87,
	-89, -90, -92, -93, -94, -96, -97, -98,
	-99, -101, -102, -103, -104, -105, -106, -107,
	-108, -109, -110, -111, -112, -113, -114, -114,
	-115, -116, -117, -117, -118, -118, -119, -119,
	-120, -120, -120, -121, -121, -121, -122, -122,
	-122, -122, -122, -122, -122, -122, -122, -122,
	-122, -122, -121, -121, -121, -120, -120, -120,
	-119, -119, -118, -118, -117, -116, -116, -115,
	-114, -113, -113, -112, -111, -110, -109, -108,
	-107, -106, -105, -104, -103, -102, -100, -99,
	-98, -97, -95, -94, -93, -91, -90, -88,
	-87, -85, -84, -82, -80, -79, -77, -76,
	-74, -72, -70, -69, -67, -65, -63, -61,
	-60, -58, -56, -54, -52, -50, -48, -46,
	-44, -42, -40, -38, -36, -34, -32, -30,
	-28, -26, -24, -22, -19, -17, -15, -13,
	-11,  -9,  -7,  -5,  -2,   0,   1,   3,
	5,   7,   9,  12,  14,  16,  18,  20,
	22,  24,  26,  28,  31,  33,  35,  37,
	39,  41,  43,  45,  47,  49,  51,  53,
	54,  56,  58,  60,  62,  64,  66,  67,
	69,  71,  73,  74,  76,  78,  79,  81,
	83,  84,  86,  87,  89,  90,  92,  93,
	94,  96,  97,  98,  99, 101, 102, 103,
	104, 105, 106, 107, 108, 109, 110, 111, 112
};

702
static const s16 hsv_blue_y[] = {
703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760
	-11, -13, -15, -17, -19, -21, -23, -25,
	-27, -29, -31, -33, -35, -37, -39, -41,
	-43, -45, -46, -48, -50, -52, -54, -55,
	-57, -59, -61, -62, -64, -66, -67, -69,
	-71, -72, -74, -75, -77, -78, -80, -81,
	-83, -84, -86, -87, -88, -90, -91, -92,
	-93, -95, -96, -97, -98, -99, -100, -101,
	-102, -103, -104, -105, -106, -106, -107, -108,
	-109, -109, -110, -111, -111, -112, -112, -113,
	-113, -114, -114, -114, -115, -115, -115, -115,
	-116, -116, -116, -116, -116, -116, -116, -116,
	-116, -115, -115, -115, -115, -114, -114, -114,
	-113, -113, -112, -112, -111, -111, -110, -110,
	-109, -108, -108, -107, -106, -105, -104, -103,
	-102, -101, -100, -99, -98, -97, -96, -95,
	-94, -93, -91, -90, -89, -88, -86, -85,
	-84, -82, -81, -79, -78, -76, -75, -73,
	-71, -70, -68, -67, -65, -63, -62, -60,
	-58, -56, -55, -53, -51, -49, -47, -45,
	-44, -42, -40, -38, -36, -34, -32, -30,
	-28, -26, -24, -22, -20, -18, -16, -14,
	-12, -10,  -8,  -6,  -4,  -2,   0,   1,
	3,   5,   7,   9,  11,  13,  15,  17,
	19,  21,  23,  25,  27,  29,  31,  33,
	35,  37,  39,  41,  43,  45,  46,  48,
	50,  52,  54,  55,  57,  59,  61,  62,
	64,  66,  67,  69,  71,  72,  74,  75,
	77,  78,  80,  81,  83,  84,  86,  87,
	88,  90,  91,  92,  93,  95,  96,  97,
	98,  99, 100, 101, 102, 103, 104, 105,
	106, 106, 107, 108, 109, 109, 110, 111,
	111, 112, 112, 113, 113, 114, 114, 114,
	115, 115, 115, 115, 116, 116, 116, 116,
	116, 116, 116, 116, 116, 115, 115, 115,
	115, 114, 114, 114, 113, 113, 112, 112,
	111, 111, 110, 110, 109, 108, 108, 107,
	106, 105, 104, 103, 102, 101, 100,  99,
	98,  97,  96,  95,  94,  93,  91,  90,
	89,  88,  86,  85,  84,  82,  81,  79,
	78,  76,  75,  73,  71,  70,  68,  67,
	65,  63,  62,  60,  58,  56,  55,  53,
	51,  49,  47,  45,  44,  42,  40,  38,
	36,  34,  32,  30,  28,  26,  24,  22,
	20,  18,  16,  14,  12,  10,   8,   6,
	4,   2,   0,  -1,  -3,  -5,  -7,  -9, -11
};

static u16 i2c_ident[] = {
	V4L2_IDENT_OV9650,
	V4L2_IDENT_OV9655,
	V4L2_IDENT_SOI968,
	V4L2_IDENT_OV7660,
	V4L2_IDENT_OV7670,
	V4L2_IDENT_MT9V011,
	V4L2_IDENT_MT9V111,
	V4L2_IDENT_MT9V112,
	V4L2_IDENT_MT9M001C12ST,
	V4L2_IDENT_MT9M111,
761
	V4L2_IDENT_MT9M112,
762
	V4L2_IDENT_HV7131R,
763
[SENSOR_MT9VPRB] = V4L2_IDENT_UNKNOWN,
764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784
};

static u16 bridge_init[][2] = {
	{0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
	{0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
	{0x1068, 0x30}, {0x1069, 0x20},	{0x106a, 0x10},
	{0x106b, 0x08},	{0x1188, 0x87},	{0x11a1, 0x00},
	{0x11a2, 0x00},	{0x11a3, 0x6a},	{0x11a4, 0x50},
	{0x11ab, 0x00},	{0x11ac, 0x00},	{0x11ad, 0x50},
	{0x11ae, 0x3c},	{0x118a, 0x04},	{0x0395, 0x04},
	{0x11b8, 0x3a},	{0x118b, 0x0e},	{0x10f7, 0x05},
	{0x10f8, 0x14},	{0x10fa, 0xff},	{0x10f9, 0x00},
	{0x11ba, 0x0a},	{0x11a5, 0x2d},	{0x11a6, 0x2d},
	{0x11a7, 0x3a},	{0x11a8, 0x05},	{0x11a9, 0x04},
	{0x11aa, 0x3f},	{0x11af, 0x28},	{0x11b0, 0xd8},
	{0x11b1, 0x14},	{0x11b2, 0xec},	{0x11b3, 0x32},
	{0x11b4, 0xdd},	{0x11b5, 0x32},	{0x11b6, 0xdd},
	{0x10e0, 0x2c},	{0x11bc, 0x40},	{0x11bd, 0x01},
	{0x11be, 0xf0},	{0x11bf, 0x00},	{0x118c, 0x1f},
	{0x118d, 0x1f},	{0x118e, 0x1f},	{0x118f, 0x1f},
	{0x1180, 0x01},	{0x1181, 0x00},	{0x1182, 0x01},
785 786
	{0x1183, 0x00},	{0x1184, 0x50},	{0x1185, 0x80},
	{0x1007, 0x00}
787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853
};

/* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
static u8 ov_gain[] = {
	0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
	0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
	0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
	0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
	0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
	0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
	0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
	0x70 /* 8x */
};

/* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
static u16 micron1_gain[] = {
	/* 1x   1.25x   1.5x    1.75x */
	0x0020, 0x0028, 0x0030, 0x0038,
	/* 2x   2.25x   2.5x    2.75x */
	0x00a0, 0x00a4, 0x00a8, 0x00ac,
	/* 3x   3.25x   3.5x    3.75x */
	0x00b0, 0x00b4, 0x00b8, 0x00bc,
	/* 4x   4.25x   4.5x    4.75x */
	0x00c0, 0x00c4, 0x00c8, 0x00cc,
	/* 5x   5.25x   5.5x    5.75x */
	0x00d0, 0x00d4, 0x00d8, 0x00dc,
	/* 6x   6.25x   6.5x    6.75x */
	0x00e0, 0x00e4, 0x00e8, 0x00ec,
	/* 7x   7.25x   7.5x    7.75x */
	0x00f0, 0x00f4, 0x00f8, 0x00fc,
	/* 8x */
	0x01c0
};

/* mt9m001 sensor uses a different gain formula then other micron sensors */
/* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
static u16 micron2_gain[] = {
	/* 1x   1.25x   1.5x    1.75x */
	0x0008, 0x000a, 0x000c, 0x000e,
	/* 2x   2.25x   2.5x    2.75x */
	0x0010, 0x0012, 0x0014, 0x0016,
	/* 3x   3.25x   3.5x    3.75x */
	0x0018, 0x001a, 0x001c, 0x001e,
	/* 4x   4.25x   4.5x    4.75x */
	0x0020, 0x0051, 0x0052, 0x0053,
	/* 5x   5.25x   5.5x    5.75x */
	0x0054, 0x0055, 0x0056, 0x0057,
	/* 6x   6.25x   6.5x    6.75x */
	0x0058, 0x0059, 0x005a, 0x005b,
	/* 7x   7.25x   7.5x    7.75x */
	0x005c, 0x005d, 0x005e, 0x005f,
	/* 8x */
	0x0060
};

/* Gain = .5 + bit[7:0] / 16 */
static u8 hv7131r_gain[] = {
	0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
	0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
	0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
	0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
	0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
	0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
	0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
	0x78 /* 8x */
};

854
static struct i2c_reg_u8 soi968_init[] = {
855
	{0x0c, 0x00}, {0x0f, 0x1f},
856 857 858 859 860
	{0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
	{0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
	{0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
	{0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
	{0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
861
	{0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
862 863 864 865 866 867
	{0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
	{0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
	{0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
	{0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
};

868
static struct i2c_reg_u8 ov7660_init[] = {
869 870 871
	{0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
	{0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
	{0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
872 873 874
	/* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
	   0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
	{0x17, 0x10}, {0x18, 0x61},
875 876 877 878 879
	{0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
	{0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
	{0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
};

880
static struct i2c_reg_u8 ov7670_init[] = {
881
	{0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936
	{0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
	{0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
	{0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
	{0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
	{0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
	{0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
	{0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
	{0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
	{0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
	{0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
	{0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
	{0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
	{0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
	{0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
	{0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
	{0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
	{0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
	{0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
	{0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
	{0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
	{0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
	{0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
	{0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
	{0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
	{0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
	{0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
	{0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
	{0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
	{0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
	{0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
	{0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
	{0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
	{0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
	{0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
	{0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
	{0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
	{0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
	{0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
	{0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
	{0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
	{0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
	{0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
	{0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
	{0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
	{0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
	{0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
	{0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
	{0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
	{0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
	{0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
	{0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
	{0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
	{0x93, 0x00},
};

937
static struct i2c_reg_u8 ov9650_init[] = {
938
	{0x00, 0x00}, {0x01, 0x78},
939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966
	{0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
	{0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
	{0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
	{0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
	{0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
	{0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
	{0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
	{0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
	{0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
	{0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
	{0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
	{0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
	{0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
	{0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
	{0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
	{0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
	{0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
	{0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
	{0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
	{0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
	{0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
	{0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
	{0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
	{0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
	{0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
	{0xaa, 0x92}, {0xab, 0x0a},
};

967
static struct i2c_reg_u8 ov9655_init[] = {
968
	{0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
969 970 971 972 973 974 975 976 977 978 979 980 981 982 983
	{0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
	{0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
	{0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
	{0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
	{0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
	{0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
	{0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
	{0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
	{0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
	{0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
	{0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
	{0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
	{0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
	{0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
	{0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
984
	{0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
985 986
	{0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
	{0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
987
	{0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
988 989 990 991
	{0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
	{0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
	{0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
	{0x04, 0x03}, {0x00, 0x13},
992 993
};

994
static struct i2c_reg_u16 mt9v112_init[] = {
995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
	{0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
	{0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
	{0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
	{0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
	{0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
	{0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
	{0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
	{0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
	{0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
	{0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
	{0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
	{0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
	{0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
	{0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
	{0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
	{0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
};

1013
static struct i2c_reg_u16 mt9v111_init[] = {
1014
	{0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
1015 1016 1017 1018 1019 1020
	{0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
	{0x2e, 0x0c64},	{0x2f, 0x0064}, {0x06, 0x600e},
	{0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
	{0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
	{0x06, 0x002d},	{0x07, 0x3002}, {0x08, 0x0008},
	{0x0e, 0x0008}, {0x20, 0x0000}
1021 1022
};

1023
static struct i2c_reg_u16 mt9v011_init[] = {
1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049
	{0x07, 0x0002},	{0x0d, 0x0001},	{0x0d, 0x0000},
	{0x01, 0x0008},	{0x02, 0x0016},	{0x03, 0x01e1},
	{0x04, 0x0281},	{0x05, 0x0083},	{0x06, 0x0006},
	{0x0d, 0x0002}, {0x0a, 0x0000},	{0x0b, 0x0000},
	{0x0c, 0x0000},	{0x0d, 0x0000},	{0x0e, 0x0000},
	{0x0f, 0x0000},	{0x10, 0x0000},	{0x11, 0x0000},
	{0x12, 0x0000},	{0x13, 0x0000},	{0x14, 0x0000},
	{0x15, 0x0000},	{0x16, 0x0000},	{0x17, 0x0000},
	{0x18, 0x0000},	{0x19, 0x0000},	{0x1a, 0x0000},
	{0x1b, 0x0000},	{0x1c, 0x0000},	{0x1d, 0x0000},
	{0x32, 0x0000},	{0x20, 0x1101},	{0x21, 0x0000},
	{0x22, 0x0000},	{0x23, 0x0000},	{0x24, 0x0000},
	{0x25, 0x0000},	{0x26, 0x0000},	{0x27, 0x0024},
	{0x2f, 0xf7b0},	{0x30, 0x0005},	{0x31, 0x0000},
	{0x32, 0x0000},	{0x33, 0x0000},	{0x34, 0x0100},
	{0x3d, 0x068f},	{0x40, 0x01e0},	{0x41, 0x00d1},
	{0x44, 0x0082},	{0x5a, 0x0000},	{0x5b, 0x0000},
	{0x5c, 0x0000},	{0x5d, 0x0000},	{0x5e, 0x0000},
	{0x5f, 0xa31d},	{0x62, 0x0611},	{0x0a, 0x0000},
	{0x06, 0x0029},	{0x05, 0x0009},	{0x20, 0x1101},
	{0x20, 0x1101},	{0x09, 0x0064},	{0x07, 0x0003},
	{0x2b, 0x0033},	{0x2c, 0x00a0},	{0x2d, 0x00a0},
	{0x2e, 0x0033},	{0x07, 0x0002},	{0x06, 0x0000},
	{0x06, 0x0029},	{0x05, 0x0009},
};

1050
static struct i2c_reg_u16 mt9m001_init[] = {
1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063
	{0x0d, 0x0001},
	{0x0d, 0x0000},
	{0x04, 0x0500},		/* hres = 1280 */
	{0x03, 0x0400},		/* vres = 1024 */
	{0x20, 0x1100},
	{0x06, 0x0010},
	{0x2b, 0x0024},
	{0x2e, 0x0024},
	{0x35, 0x0024},
	{0x2d, 0x0020},
	{0x2c, 0x0020},
	{0x09, 0x0ad4},
	{0x35, 0x0057},
1064 1065
};

1066
static struct i2c_reg_u16 mt9m111_init[] = {
1067 1068
	{0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
	{0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
1069 1070
	{0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
	{0xf0, 0x0000},
1071 1072
};

1073 1074 1075 1076 1077 1078 1079
static struct i2c_reg_u16 mt9m112_init[] = {
	{0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
	{0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
	{0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
	{0xf0, 0x0000},
};

1080
static struct i2c_reg_u8 hv7131r_init[] = {
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090
	{0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
	{0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
	{0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
	{0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
	{0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
	{0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
	{0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
	{0x23, 0x09}, {0x01, 0x08},
};

1091
static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
1092 1093 1094
{
	struct usb_device *dev = gspca_dev->dev;
	int result;
1095 1096 1097

	if (gspca_dev->usb_err < 0)
		return;
1098 1099 1100 1101 1102 1103 1104 1105 1106
	result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
			0x00,
			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
			reg,
			0x00,
			gspca_dev->usb_buf,
			length,
			500);
	if (unlikely(result < 0 || result != length)) {
1107 1108
		pr_err("Read register %02x failed %d\n", reg, result);
		gspca_dev->usb_err = result;
1109 1110 1111
	}
}

1112
static void reg_w(struct gspca_dev *gspca_dev, u16 reg,
1113
		 const u8 *buffer, int length)
1114 1115 1116
{
	struct usb_device *dev = gspca_dev->dev;
	int result;
1117 1118 1119

	if (gspca_dev->usb_err < 0)
		return;
1120 1121 1122 1123 1124 1125 1126 1127 1128 1129
	memcpy(gspca_dev->usb_buf, buffer, length);
	result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
			0x08,
			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
			reg,
			0x00,
			gspca_dev->usb_buf,
			length,
			500);
	if (unlikely(result < 0 || result != length)) {
1130 1131
		pr_err("Write register %02x failed %d\n", reg, result);
		gspca_dev->usb_err = result;
1132 1133 1134
	}
}

1135
static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
1136
{
1137
	reg_w(gspca_dev, reg, &value, 1);
1138 1139
}

1140
static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
1141 1142
{
	int i;
1143

1144 1145 1146
	reg_w(gspca_dev, 0x10c0, buffer, 8);
	for (i = 0; i < 5; i++) {
		reg_r(gspca_dev, 0x10c0, 1);
1147 1148
		if (gspca_dev->usb_err < 0)
			return;
1149
		if (gspca_dev->usb_buf[0] & 0x04) {
1150 1151 1152 1153 1154
			if (gspca_dev->usb_buf[0] & 0x08) {
				pr_err("i2c_w error\n");
				gspca_dev->usb_err = -EIO;
			}
			return;
1155
		}
1156
		msleep(10);
1157
	}
1158 1159
	pr_err("i2c_w reg %02x no response\n", buffer[2]);
/*	gspca_dev->usb_err = -EIO;	fixme: may occur */
1160 1161
}

1162
static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179
{
	struct sd *sd = (struct sd *) gspca_dev;
	u8 row[8];

	/*
	 * from the point of view of the bridge, the length
	 * includes the address
	 */
	row[0] = 0x81 | (2 << 4);
	row[1] = sd->i2c_addr;
	row[2] = reg;
	row[3] = val;
	row[4] = 0x00;
	row[5] = 0x00;
	row[6] = 0x00;
	row[7] = 0x10;

1180
	i2c_w(gspca_dev, row);
1181 1182
}

1183 1184 1185 1186 1187 1188 1189 1190 1191
static void i2c_w1_buf(struct gspca_dev *gspca_dev,
			struct i2c_reg_u8 *buf, int sz)
{
	while (--sz >= 0) {
		i2c_w1(gspca_dev, buf->reg, buf->val);
		buf++;
	}
}

1192
static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203
{
	struct sd *sd = (struct sd *) gspca_dev;
	u8 row[8];

	/*
	 * from the point of view of the bridge, the length
	 * includes the address
	 */
	row[0] = 0x81 | (3 << 4);
	row[1] = sd->i2c_addr;
	row[2] = reg;
1204 1205
	row[3] = val >> 8;
	row[4] = val;
1206 1207 1208 1209
	row[5] = 0x00;
	row[6] = 0x00;
	row[7] = 0x10;

1210
	i2c_w(gspca_dev, row);
1211 1212
}

1213 1214 1215 1216 1217 1218 1219 1220 1221
static void i2c_w2_buf(struct gspca_dev *gspca_dev,
			struct i2c_reg_u16 *buf, int sz)
{
	while (--sz >= 0) {
		i2c_w2(gspca_dev, buf->reg, buf->val);
		buf++;
	}
}

1222
static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1223 1224 1225 1226
{
	struct sd *sd = (struct sd *) gspca_dev;
	u8 row[8];

1227
	row[0] = 0x81 | (1 << 4);
1228 1229 1230 1231 1232 1233 1234
	row[1] = sd->i2c_addr;
	row[2] = reg;
	row[3] = 0;
	row[4] = 0;
	row[5] = 0;
	row[6] = 0;
	row[7] = 0x10;
1235
	i2c_w(gspca_dev, row);
1236
	row[0] = 0x81 | (1 << 4) | 0x02;
1237
	row[2] = 0;
1238 1239
	i2c_w(gspca_dev, row);
	reg_r(gspca_dev, 0x10c2, 5);
1240
	*val = gspca_dev->usb_buf[4];
1241 1242
}

1243
static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1244 1245 1246 1247
{
	struct sd *sd = (struct sd *) gspca_dev;
	u8 row[8];

1248
	row[0] = 0x81 | (1 << 4);
1249 1250 1251 1252 1253 1254 1255
	row[1] = sd->i2c_addr;
	row[2] = reg;
	row[3] = 0;
	row[4] = 0;
	row[5] = 0;
	row[6] = 0;
	row[7] = 0x10;
1256
	i2c_w(gspca_dev, row);
1257
	row[0] = 0x81 | (2 << 4) | 0x02;
1258
	row[2] = 0;
1259 1260
	i2c_w(gspca_dev, row);
	reg_r(gspca_dev, 0x10c2, 5);
1261
	*val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1262 1263
}

1264
static void ov9650_init_sensor(struct gspca_dev *gspca_dev)
1265
{
1266
	u16 id;
1267 1268
	struct sd *sd = (struct sd *) gspca_dev;

1269 1270 1271
	i2c_r2(gspca_dev, 0x1c, &id);
	if (gspca_dev->usb_err < 0)
		return;
1272 1273

	if (id != 0x7fa2) {
1274
		pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id);
1275 1276
		gspca_dev->usb_err = -ENODEV;
		return;
1277 1278
	}

1279 1280
	i2c_w1(gspca_dev, 0x12, 0x80);		/* sensor reset */
	msleep(200);
1281 1282 1283
	i2c_w1_buf(gspca_dev, ov9650_init, ARRAY_SIZE(ov9650_init));
	if (gspca_dev->usb_err < 0)
		pr_err("OV9650 sensor initialization failed\n");
1284 1285 1286 1287
	sd->hstart = 1;
	sd->vstart = 7;
}

1288
static void ov9655_init_sensor(struct gspca_dev *gspca_dev)
1289 1290 1291
{
	struct sd *sd = (struct sd *) gspca_dev;

1292 1293
	i2c_w1(gspca_dev, 0x12, 0x80);		/* sensor reset */
	msleep(200);
1294 1295 1296 1297
	i2c_w1_buf(gspca_dev, ov9655_init, ARRAY_SIZE(ov9655_init));
	if (gspca_dev->usb_err < 0)
		pr_err("OV9655 sensor initialization failed\n");

1298
	/* disable hflip and vflip */
1299
	gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1300 1301
	sd->hstart = 1;
	sd->vstart = 2;
1302 1303
}

1304
static void soi968_init_sensor(struct gspca_dev *gspca_dev)
1305 1306 1307
{
	struct sd *sd = (struct sd *) gspca_dev;

1308 1309
	i2c_w1(gspca_dev, 0x12, 0x80);		/* sensor reset */
	msleep(200);
1310 1311 1312 1313
	i2c_w1_buf(gspca_dev, soi968_init, ARRAY_SIZE(soi968_init));
	if (gspca_dev->usb_err < 0)
		pr_err("SOI968 sensor initialization failed\n");

1314
	/* disable hflip and vflip */
1315 1316
	gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP)
				| (1 << EXPOSURE);
1317 1318 1319 1320
	sd->hstart = 60;
	sd->vstart = 11;
}

1321
static void ov7660_init_sensor(struct gspca_dev *gspca_dev)
1322 1323 1324
{
	struct sd *sd = (struct sd *) gspca_dev;

1325 1326
	i2c_w1(gspca_dev, 0x12, 0x80);		/* sensor reset */
	msleep(200);
1327 1328 1329
	i2c_w1_buf(gspca_dev, ov7660_init, ARRAY_SIZE(ov7660_init));
	if (gspca_dev->usb_err < 0)
		pr_err("OV7660 sensor initialization failed\n");
1330 1331
	sd->hstart = 3;
	sd->vstart = 3;
1332 1333
}

1334
static void ov7670_init_sensor(struct gspca_dev *gspca_dev)
1335 1336 1337
{
	struct sd *sd = (struct sd *) gspca_dev;

1338 1339
	i2c_w1(gspca_dev, 0x12, 0x80);		/* sensor reset */
	msleep(200);
1340 1341 1342 1343
	i2c_w1_buf(gspca_dev, ov7670_init, ARRAY_SIZE(ov7670_init));
	if (gspca_dev->usb_err < 0)
		pr_err("OV7670 sensor initialization failed\n");

1344
	/* disable hflip and vflip */
1345
	gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1346 1347 1348 1349
	sd->hstart = 0;
	sd->vstart = 1;
}

1350
static void mt9v_init_sensor(struct gspca_dev *gspca_dev)
1351 1352 1353 1354 1355
{
	struct sd *sd = (struct sd *) gspca_dev;
	u16 value;

	sd->i2c_addr = 0x5d;
1356 1357 1358
	i2c_r2(gspca_dev, 0xff, &value);
	if (gspca_dev->usb_err >= 0
	 && value == 0x8243) {
1359 1360 1361 1362
		i2c_w2_buf(gspca_dev, mt9v011_init, ARRAY_SIZE(mt9v011_init));
		if (gspca_dev->usb_err < 0) {
			pr_err("MT9V011 sensor initialization failed\n");
			return;
1363 1364 1365 1366
		}
		sd->hstart = 2;
		sd->vstart = 2;
		sd->sensor = SENSOR_MT9V011;
1367
		pr_info("MT9V011 sensor detected\n");
1368
		return;
1369 1370
	}

1371
	gspca_dev->usb_err = 0;
1372 1373
	sd->i2c_addr = 0x5c;
	i2c_w2(gspca_dev, 0x01, 0x0004);
1374 1375 1376
	i2c_r2(gspca_dev, 0xff, &value);
	if (gspca_dev->usb_err >= 0
	 && value == 0x823a) {
1377 1378 1379 1380
		i2c_w2_buf(gspca_dev, mt9v111_init, ARRAY_SIZE(mt9v111_init));
		if (gspca_dev->usb_err < 0) {
			pr_err("MT9V111 sensor initialization failed\n");
			return;
1381
		}
1382 1383 1384
		gspca_dev->ctrl_dis = (1 << EXPOSURE)
					| (1 << AUTOGAIN)
					| (1 << GAIN);
1385 1386 1387
		sd->hstart = 2;
		sd->vstart = 2;
		sd->sensor = SENSOR_MT9V111;
1388
		pr_info("MT9V111 sensor detected\n");
1389
		return;
1390 1391
	}

1392
	gspca_dev->usb_err = 0;
1393
	sd->i2c_addr = 0x5d;
1394 1395 1396
	i2c_w2(gspca_dev, 0xf0, 0x0000);
	if (gspca_dev->usb_err < 0) {
		gspca_dev->usb_err = 0;
1397 1398 1399
		sd->i2c_addr = 0x48;
		i2c_w2(gspca_dev, 0xf0, 0x0000);
	}
1400 1401 1402
	i2c_r2(gspca_dev, 0x00, &value);
	if (gspca_dev->usb_err >= 0
	 && value == 0x1229) {
1403 1404 1405 1406
		i2c_w2_buf(gspca_dev, mt9v112_init, ARRAY_SIZE(mt9v112_init));
		if (gspca_dev->usb_err < 0) {
			pr_err("MT9V112 sensor initialization failed\n");
			return;
1407 1408 1409 1410
		}
		sd->hstart = 6;
		sd->vstart = 2;
		sd->sensor = SENSOR_MT9V112;
1411
		pr_info("MT9V112 sensor detected\n");
1412
		return;
1413 1414
	}

1415
	gspca_dev->usb_err = -ENODEV;
1416 1417
}

1418
static void mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1419 1420
{
	struct sd *sd = (struct sd *) gspca_dev;
1421 1422 1423 1424 1425

	i2c_w2_buf(gspca_dev, mt9m112_init, ARRAY_SIZE(mt9m112_init));
	if (gspca_dev->usb_err < 0)
		pr_err("MT9M112 sensor initialization failed\n");

1426 1427
	gspca_dev->ctrl_dis = (1 << EXPOSURE) | (1 << AUTOGAIN)
				| (1 << GAIN);
1428 1429 1430 1431
	sd->hstart = 0;
	sd->vstart = 2;
}

1432
static void mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1433 1434
{
	struct sd *sd = (struct sd *) gspca_dev;
1435 1436 1437 1438 1439

	i2c_w2_buf(gspca_dev, mt9m111_init, ARRAY_SIZE(mt9m111_init));
	if (gspca_dev->usb_err < 0)
		pr_err("MT9M111 sensor initialization failed\n");

1440 1441
	gspca_dev->ctrl_dis = (1 << EXPOSURE) | (1 << AUTOGAIN)
				| (1 << GAIN);
1442 1443 1444 1445
	sd->hstart = 0;
	sd->vstart = 2;
}

1446
static void mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1447 1448
{
	struct sd *sd = (struct sd *) gspca_dev;
1449 1450
	u16 id;

1451 1452 1453
	i2c_r2(gspca_dev, 0x00, &id);
	if (gspca_dev->usb_err < 0)
		return;
1454 1455 1456 1457 1458

	/* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
	switch (id) {
	case 0x8411:
	case 0x8421:
1459
		pr_info("MT9M001 color sensor detected\n");
1460 1461
		break;
	case 0x8431:
1462
		pr_info("MT9M001 mono sensor detected\n");
1463 1464
		break;
	default:
1465
		pr_err("No MT9M001 chip detected, ID = %x\n\n", id);
1466 1467
		gspca_dev->usb_err = -ENODEV;
		return;
1468 1469
	}

1470 1471 1472 1473
	i2c_w2_buf(gspca_dev, mt9m001_init, ARRAY_SIZE(mt9m001_init));
	if (gspca_dev->usb_err < 0)
		pr_err("MT9M001 sensor initialization failed\n");

1474
	/* disable hflip and vflip */
1475
	gspca_dev->ctrl_dis = (1 << HFLIP) | (1 << VFLIP);
1476 1477
	sd->hstart = 1;
	sd->vstart = 1;
1478 1479
}

1480
static void hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1481 1482 1483
{
	struct sd *sd = (struct sd *) gspca_dev;

1484 1485 1486 1487
	i2c_w1_buf(gspca_dev, hv7131r_init, ARRAY_SIZE(hv7131r_init));
	if (gspca_dev->usb_err < 0)
		pr_err("HV7131R Sensor initialization failed\n");

1488 1489 1490 1491
	sd->hstart = 0;
	sd->vstart = 1;
}

1492
static void set_cmatrix(struct gspca_dev *gspca_dev)
1493 1494
{
	struct sd *sd = (struct sd *) gspca_dev;
1495 1496
	int satur;
	s32 hue_coord, hue_index = 180 + sd->ctrls[HUE].val;
1497 1498
	u8 cmatrix[21];

1499
	memset(cmatrix, 0, sizeof cmatrix);
1500
	cmatrix[2] = (sd->ctrls[CONTRAST].val * 0x25 / 0x100) + 0x26;
1501 1502
	cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
	cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1503
	cmatrix[18] = sd->ctrls[BRIGHTNESS].val - 0x80;
1504

1505 1506
	satur = sd->ctrls[SATURATION].val;
	hue_coord = (hsv_red_x[hue_index] * satur) >> 8;
1507 1508
	cmatrix[6] = hue_coord;
	cmatrix[7] = (hue_coord >> 8) & 0x0f;
1509

1510
	hue_coord = (hsv_red_y[hue_index] * satur) >> 8;
1511 1512
	cmatrix[8] = hue_coord;
	cmatrix[9] = (hue_coord >> 8) & 0x0f;
1513

1514
	hue_coord = (hsv_green_x[hue_index] * satur) >> 8;
1515 1516
	cmatrix[10] = hue_coord;
	cmatrix[11] = (hue_coord >> 8) & 0x0f;
1517

1518
	hue_coord = (hsv_green_y[hue_index] * satur) >> 8;
1519 1520
	cmatrix[12] = hue_coord;
	cmatrix[13] = (hue_coord >> 8) & 0x0f;
1521

1522
	hue_coord = (hsv_blue_x[hue_index] * satur) >> 8;
1523 1524
	cmatrix[14] = hue_coord;
	cmatrix[15] = (hue_coord >> 8) & 0x0f;
1525

1526
	hue_coord = (hsv_blue_y[hue_index] * satur) >> 8;
1527 1528
	cmatrix[16] = hue_coord;
	cmatrix[17] = (hue_coord >> 8) & 0x0f;
1529

1530
	reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1531 1532
}

1533
static void set_gamma(struct gspca_dev *gspca_dev)
1534 1535 1536
{
	struct sd *sd = (struct sd *) gspca_dev;
	u8 gamma[17];
1537
	u8 gval = sd->ctrls[GAMMA].val * 0xb8 / 0x100;
1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556

	gamma[0] = 0x0a;
	gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
	gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
	gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
	gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
	gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
	gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
	gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
	gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
	gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
	gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
	gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
	gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
	gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
	gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
	gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
	gamma[16] = 0xf5;

1557
	reg_w(gspca_dev, 0x1190, gamma, 17);
1558 1559
}

1560
static void set_redblue(struct gspca_dev *gspca_dev)
1561 1562
{
	struct sd *sd = (struct sd *) gspca_dev;
1563 1564 1565

	reg_w1(gspca_dev, 0x118c, sd->ctrls[RED].val);
	reg_w1(gspca_dev, 0x118f, sd->ctrls[BLUE].val);
1566 1567
}

1568
static void set_hvflip(struct gspca_dev *gspca_dev)
1569
{
1570
	u8 value, tslb, hflip, vflip;
1571 1572
	u16 value2;
	struct sd *sd = (struct sd *) gspca_dev;
1573 1574

	if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1575 1576
		hflip = !sd->ctrls[HFLIP].val;
		vflip = !sd->ctrls[VFLIP].val;
1577
	} else {
1578 1579
		hflip = sd->ctrls[HFLIP].val;
		vflip = sd->ctrls[VFLIP].val;
1580 1581
	}

1582
	switch (sd->sensor) {
1583 1584 1585 1586 1587 1588 1589
	case SENSOR_OV7660:
		value = 0x01;
		if (hflip)
			value |= 0x20;
		if (vflip) {
			value |= 0x10;
			sd->vstart = 2;
1590
		} else {
1591
			sd->vstart = 3;
1592
		}
1593 1594 1595
		reg_w1(gspca_dev, 0x1182, sd->vstart);
		i2c_w1(gspca_dev, 0x1e, value);
		break;
1596 1597 1598 1599
	case SENSOR_OV9650:
		i2c_r1(gspca_dev, 0x1e, &value);
		value &= ~0x30;
		tslb = 0x01;
1600
		if (hflip)
1601
			value |= 0x20;
1602
		if (vflip) {
1603 1604 1605 1606 1607 1608 1609 1610 1611 1612
			value |= 0x10;
			tslb = 0x49;
		}
		i2c_w1(gspca_dev, 0x1e, value);
		i2c_w1(gspca_dev, 0x3a, tslb);
		break;
	case SENSOR_MT9V111:
	case SENSOR_MT9V011:
		i2c_r2(gspca_dev, 0x20, &value2);
		value2 &= ~0xc0a0;
1613
		if (hflip)
1614
			value2 |= 0x8080;
1615
		if (vflip)
1616 1617 1618
			value2 |= 0x4020;
		i2c_w2(gspca_dev, 0x20, value2);
		break;
1619
	case SENSOR_MT9M112:
1620 1621 1622 1623
	case SENSOR_MT9M111:
	case SENSOR_MT9V112:
		i2c_r2(gspca_dev, 0x20, &value2);
		value2 &= ~0x0003;
1624
		if (hflip)
1625
			value2 |= 0x0002;
1626
		if (vflip)
1627 1628 1629 1630 1631 1632
			value2 |= 0x0001;
		i2c_w2(gspca_dev, 0x20, value2);
		break;
	case SENSOR_HV7131R:
		i2c_r1(gspca_dev, 0x01, &value);
		value &= ~0x03;
1633
		if (vflip)
1634
			value |= 0x01;
1635
		if (hflip)
1636 1637 1638 1639 1640 1641
			value |= 0x02;
		i2c_w1(gspca_dev, 0x01, value);
		break;
	}
}

1642
static void set_exposure(struct gspca_dev *gspca_dev)
1643 1644 1645
{
	struct sd *sd = (struct sd *) gspca_dev;
	u8 exp[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e};
1646 1647 1648
	int expo;

	expo = sd->ctrls[EXPOSURE].val;
1649 1650 1651 1652 1653 1654 1655
	switch (sd->sensor) {
	case SENSOR_OV7660:
	case SENSOR_OV7670:
	case SENSOR_OV9655:
	case SENSOR_OV9650:
		exp[0] |= (3 << 4);
		exp[2] = 0x2d;
1656 1657
		exp[3] = expo;
		exp[4] = expo >> 8;
1658 1659 1660 1661 1662 1663
		break;
	case SENSOR_MT9M001:
	case SENSOR_MT9V112:
	case SENSOR_MT9V011:
		exp[0] |= (3 << 4);
		exp[2] = 0x09;
1664 1665
		exp[3] = expo >> 8;
		exp[4] = expo;
1666 1667 1668 1669
		break;
	case SENSOR_HV7131R:
		exp[0] |= (4 << 4);
		exp[2] = 0x25;
1670 1671
		exp[3] = expo >> 5;
		exp[4] = expo << 3;
1672
		exp[5] = 0;
1673
		break;
1674
	default:
1675
		return;
1676 1677 1678 1679
	}
	i2c_w(gspca_dev, exp);
}

1680
static void set_gain(struct gspca_dev *gspca_dev)
1681 1682 1683
{
	struct sd *sd = (struct sd *) gspca_dev;
	u8 gain[8] = {0x81, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1d};
1684 1685 1686
	int g;

	g = sd->ctrls[GAIN].val;
1687 1688 1689 1690 1691 1692 1693
	switch (sd->sensor) {
	case SENSOR_OV7660:
	case SENSOR_OV7670:
	case SENSOR_SOI968:
	case SENSOR_OV9655:
	case SENSOR_OV9650:
		gain[0] |= (2 << 4);
1694
		gain[3] = ov_gain[g];
1695 1696 1697 1698
		break;
	case SENSOR_MT9V011:
		gain[0] |= (3 << 4);
		gain[2] = 0x35;
1699 1700
		gain[3] = micron1_gain[g] >> 8;
		gain[4] = micron1_gain[g];
1701 1702 1703 1704
		break;
	case SENSOR_MT9V112:
		gain[0] |= (3 << 4);
		gain[2] = 0x2f;
1705 1706
		gain[3] = micron1_gain[g] >> 8;
		gain[4] = micron1_gain[g];
1707 1708 1709 1710
		break;
	case SENSOR_MT9M001:
		gain[0] |= (3 << 4);
		gain[2] = 0x2f;
1711 1712
		gain[3] = micron2_gain[g] >> 8;
		gain[4] = micron2_gain[g];
1713 1714 1715 1716
		break;
	case SENSOR_HV7131R:
		gain[0] |= (2 << 4);
		gain[2] = 0x30;
1717
		gain[3] = hv7131r_gain[g];
1718
		break;
1719
	default:
1720
		return;
1721 1722 1723 1724
	}
	i2c_w(gspca_dev, gain);
}

1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739
static void set_quality(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *) gspca_dev;

	jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val);
	reg_w1(gspca_dev, 0x1061, 0x01);	/* stop transfer */
	reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */
	reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
	reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
	reg_w1(gspca_dev, 0x1061, 0x03);	/* restart transfer */
	reg_w1(gspca_dev, 0x10e0, sd->fmt);
	sd->fmt ^= 0x0c;			/* invert QTAB use + write */
	reg_w1(gspca_dev, 0x10e0, sd->fmt);
}

1740 1741 1742 1743 1744
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
			struct v4l2_dbg_register *reg)
{
	struct sd *sd = (struct sd *) gspca_dev;
1745

1746 1747 1748 1749 1750 1751
	switch (reg->match.type) {
	case V4L2_CHIP_MATCH_HOST:
		if (reg->match.addr != 0)
			return -EINVAL;
		if (reg->reg < 0x1000 || reg->reg > 0x11ff)
			return -EINVAL;
1752
		reg_r(gspca_dev, reg->reg, 1);
1753
		reg->val = gspca_dev->usb_buf[0];
1754
		return gspca_dev->usb_err;
1755 1756 1757 1758
	case V4L2_CHIP_MATCH_I2C_ADDR:
		if (reg->match.addr != sd->i2c_addr)
			return -EINVAL;
		if (sd->sensor >= SENSOR_MT9V011 &&
1759
		    sd->sensor <= SENSOR_MT9M112) {
1760
			i2c_r2(gspca_dev, reg->reg, (u16 *) &reg->val);
1761
		} else {
1762
			i2c_r1(gspca_dev, reg->reg, (u8 *) &reg->val);
1763
		}
1764
		return gspca_dev->usb_err;
1765 1766 1767 1768 1769 1770 1771 1772
	}
	return -EINVAL;
}

static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
			struct v4l2_dbg_register *reg)
{
	struct sd *sd = (struct sd *) gspca_dev;
1773

1774 1775 1776 1777 1778 1779
	switch (reg->match.type) {
	case V4L2_CHIP_MATCH_HOST:
		if (reg->match.addr != 0)
			return -EINVAL;
		if (reg->reg < 0x1000 || reg->reg > 0x11ff)
			return -EINVAL;
1780 1781
		reg_w1(gspca_dev, reg->reg, reg->val);
		return gspca_dev->usb_err;
1782 1783 1784 1785
	case V4L2_CHIP_MATCH_I2C_ADDR:
		if (reg->match.addr != sd->i2c_addr)
			return -EINVAL;
		if (sd->sensor >= SENSOR_MT9V011 &&
1786
		    sd->sensor <= SENSOR_MT9M112) {
1787
			i2c_w2(gspca_dev, reg->reg, reg->val);
1788
		} else {
1789
			i2c_w1(gspca_dev, reg->reg, reg->val);
1790
		}
1791
		return gspca_dev->usb_err;
1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825
	}
	return -EINVAL;
}
#endif

static int sd_chip_ident(struct gspca_dev *gspca_dev,
			struct v4l2_dbg_chip_ident *chip)
{
	struct sd *sd = (struct sd *) gspca_dev;

	switch (chip->match.type) {
	case V4L2_CHIP_MATCH_HOST:
		if (chip->match.addr != 0)
			return -EINVAL;
		chip->revision = 0;
		chip->ident = V4L2_IDENT_SN9C20X;
		return 0;
	case V4L2_CHIP_MATCH_I2C_ADDR:
		if (chip->match.addr != sd->i2c_addr)
			return -EINVAL;
		chip->revision = 0;
		chip->ident = i2c_ident[sd->sensor];
		return 0;
	}
	return -EINVAL;
}

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;

	cam = &gspca_dev->cam;
1826
	cam->needs_full_bandwidth = 1;
1827

1828 1829 1830
	sd->sensor = id->driver_info >> 8;
	sd->i2c_addr = id->driver_info;
	sd->flags = id->driver_info >> 16;
1831 1832

	switch (sd->sensor) {
1833
	case SENSOR_MT9M112:
1834
	case SENSOR_MT9M111:
1835
	case SENSOR_OV9650:
1836
	case SENSOR_SOI968:
1837 1838 1839
		cam->cam_mode = sxga_mode;
		cam->nmodes = ARRAY_SIZE(sxga_mode);
		break;
1840 1841 1842 1843
	case SENSOR_MT9M001:
		cam->cam_mode = mono_mode;
		cam->nmodes = ARRAY_SIZE(mono_mode);
		break;
1844 1845 1846
	default:
		cam->cam_mode = vga_mode;
		cam->nmodes = ARRAY_SIZE(vga_mode);
1847
		break;
1848 1849 1850 1851 1852 1853
	}

	sd->old_step = 0;
	sd->older_step = 0;
	sd->exposure_step = 16;

1854
	gspca_dev->cam.ctrls = sd->ctrls;
1855

1856
	INIT_WORK(&sd->work, qual_upd);
1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870

	return 0;
}

static int sd_init(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *) gspca_dev;
	int i;
	u8 value;
	u8 i2c_init[9] =
		{0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03};

	for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
		value = bridge_init[i][1];
1871 1872
		reg_w(gspca_dev, bridge_init[i][0], &value, 1);
		if (gspca_dev->usb_err < 0) {
1873
			pr_err("Device initialization failed\n");
1874
			return gspca_dev->usb_err;
1875 1876 1877
		}
	}

1878 1879 1880 1881 1882
	if (sd->flags & LED_REVERSE)
		reg_w1(gspca_dev, 0x1006, 0x00);
	else
		reg_w1(gspca_dev, 0x1006, 0x20);

1883 1884
	reg_w(gspca_dev, 0x10c0, i2c_init, 9);
	if (gspca_dev->usb_err < 0) {
1885
		pr_err("Device initialization failed\n");
1886
		return gspca_dev->usb_err;
1887 1888 1889 1890
	}

	switch (sd->sensor) {
	case SENSOR_OV9650:
1891 1892 1893
		ov9650_init_sensor(gspca_dev);
		if (gspca_dev->usb_err < 0)
			break;
1894
		pr_info("OV9650 sensor detected\n");
1895 1896
		break;
	case SENSOR_OV9655:
1897 1898 1899
		ov9655_init_sensor(gspca_dev);
		if (gspca_dev->usb_err < 0)
			break;
1900
		pr_info("OV9655 sensor detected\n");
1901 1902
		break;
	case SENSOR_SOI968:
1903 1904 1905
		soi968_init_sensor(gspca_dev);
		if (gspca_dev->usb_err < 0)
			break;
1906
		pr_info("SOI968 sensor detected\n");
1907 1908
		break;
	case SENSOR_OV7660:
1909 1910 1911
		ov7660_init_sensor(gspca_dev);
		if (gspca_dev->usb_err < 0)
			break;
1912
		pr_info("OV7660 sensor detected\n");
1913 1914
		break;
	case SENSOR_OV7670:
1915 1916 1917
		ov7670_init_sensor(gspca_dev);
		if (gspca_dev->usb_err < 0)
			break;
1918
		pr_info("OV7670 sensor detected\n");
1919 1920
		break;
	case SENSOR_MT9VPRB:
1921 1922 1923
		mt9v_init_sensor(gspca_dev);
		if (gspca_dev->usb_err < 0)
			break;
1924
		pr_info("MT9VPRB sensor detected\n");
1925 1926
		break;
	case SENSOR_MT9M111:
1927 1928 1929
		mt9m111_init_sensor(gspca_dev);
		if (gspca_dev->usb_err < 0)
			break;
1930
		pr_info("MT9M111 sensor detected\n");
1931
		break;
1932
	case SENSOR_MT9M112:
1933 1934 1935
		mt9m112_init_sensor(gspca_dev);
		if (gspca_dev->usb_err < 0)
			break;
1936
		pr_info("MT9M112 sensor detected\n");
1937
		break;
1938
	case SENSOR_MT9M001:
1939 1940 1941
		mt9m001_init_sensor(gspca_dev);
		if (gspca_dev->usb_err < 0)
			break;
1942 1943
		break;
	case SENSOR_HV7131R:
1944 1945 1946
		hv7131r_init_sensor(gspca_dev);
		if (gspca_dev->usb_err < 0)
			break;
1947
		pr_info("HV7131R sensor detected\n");
1948 1949
		break;
	default:
1950
		pr_err("Unsupported sensor\n");
1951
		gspca_dev->usb_err = -ENODEV;
1952 1953
	}

1954
	return gspca_dev->usb_err;
1955 1956 1957 1958 1959 1960
}

static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
{
	struct sd *sd = (struct sd *) gspca_dev;
	u8 value;
1961

1962
	switch (sd->sensor) {
1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981
	case SENSOR_SOI968:
		if (mode & MODE_SXGA) {
			i2c_w1(gspca_dev, 0x17, 0x1d);
			i2c_w1(gspca_dev, 0x18, 0xbd);
			i2c_w1(gspca_dev, 0x19, 0x01);
			i2c_w1(gspca_dev, 0x1a, 0x81);
			i2c_w1(gspca_dev, 0x12, 0x00);
			sd->hstart = 140;
			sd->vstart = 19;
		} else {
			i2c_w1(gspca_dev, 0x17, 0x13);
			i2c_w1(gspca_dev, 0x18, 0x63);
			i2c_w1(gspca_dev, 0x19, 0x01);
			i2c_w1(gspca_dev, 0x1a, 0x79);
			i2c_w1(gspca_dev, 0x12, 0x40);
			sd->hstart = 60;
			sd->vstart = 11;
		}
		break;
1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998
	case SENSOR_OV9650:
		if (mode & MODE_SXGA) {
			i2c_w1(gspca_dev, 0x17, 0x1b);
			i2c_w1(gspca_dev, 0x18, 0xbc);
			i2c_w1(gspca_dev, 0x19, 0x01);
			i2c_w1(gspca_dev, 0x1a, 0x82);
			i2c_r1(gspca_dev, 0x12, &value);
			i2c_w1(gspca_dev, 0x12, value & 0x07);
		} else {
			i2c_w1(gspca_dev, 0x17, 0x24);
			i2c_w1(gspca_dev, 0x18, 0xc5);
			i2c_w1(gspca_dev, 0x19, 0x00);
			i2c_w1(gspca_dev, 0x1a, 0x3c);
			i2c_r1(gspca_dev, 0x12, &value);
			i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
		}
		break;
1999
	case SENSOR_MT9M112:
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010
	case SENSOR_MT9M111:
		if (mode & MODE_SXGA) {
			i2c_w2(gspca_dev, 0xf0, 0x0002);
			i2c_w2(gspca_dev, 0xc8, 0x970b);
			i2c_w2(gspca_dev, 0xf0, 0x0000);
		} else {
			i2c_w2(gspca_dev, 0xf0, 0x0002);
			i2c_w2(gspca_dev, 0xc8, 0x8000);
			i2c_w2(gspca_dev, 0xf0, 0x0000);
		}
		break;
2011 2012 2013
	}
}

2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043
static int sd_isoc_init(struct gspca_dev *gspca_dev)
{
	struct usb_interface *intf;
	u32 flags = gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv;

	/*
	 * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
	 * than our regular bandwidth calculations reserve, so we force the
	 * use of a specific altsetting when using the SN9C20X_I420 fmt.
	 */
	if (!(flags & (MODE_RAW | MODE_JPEG))) {
		intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);

		if (intf->num_altsetting != 9) {
			pr_warn("sn9c20x camera with unknown number of alt "
			        "settings (%d), please report!\n",
			        intf->num_altsetting);
			gspca_dev->alt = intf->num_altsetting;
			return 0;
		}

		switch (gspca_dev->width) {
		case 160: /* 160x120 */
			gspca_dev->alt = 2;
			break;
		case 320: /* 320x240 */
			gspca_dev->alt = 6;
			break;
		default:  /* >= 640x480 */
			gspca_dev->alt = 9;
2044
			break;
2045 2046 2047 2048 2049 2050
		}
	}

	return 0;
}

2051
#define HW_WIN(mode, hstart, vstart) \
2052
((const u8 []){hstart, 0, vstart, 0, \
2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070
(mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
(mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})

#define CLR_WIN(width, height) \
((const u8 [])\
{0, width >> 2, 0, height >> 1,\
((width >> 10) & 0x01) | ((height >> 8) & 0x6)})

static int sd_start(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *) gspca_dev;
	int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
	int width = gspca_dev->width;
	int height = gspca_dev->height;
	u8 fmt, scale = 0;

	jpeg_define(sd->jpeg_hdr, height, width,
			0x21);
2071
	jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val);
2072 2073 2074 2075

	if (mode & MODE_RAW)
		fmt = 0x2d;
	else if (mode & MODE_JPEG)
2076
		fmt = 0x24;
2077
	else
2078
		fmt = 0x2f;	/* YUV 420 */
2079
	sd->fmt = fmt;
2080

2081 2082
	switch (mode & SCALE_MASK) {
	case SCALE_1280x1024:
2083
		scale = 0xc0;
2084
		pr_info("Set 1280x1024\n");
2085
		break;
2086
	case SCALE_640x480:
2087
		scale = 0x80;
2088
		pr_info("Set 640x480\n");
2089
		break;
2090
	case SCALE_320x240:
2091
		scale = 0x90;
2092
		pr_info("Set 320x240\n");
2093
		break;
2094
	case SCALE_160x120:
2095
		scale = 0xa0;
2096
		pr_info("Set 160x120\n");
2097 2098 2099 2100
		break;
	}

	configure_sensor_output(gspca_dev, mode);
2101 2102
	reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
	reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114
	reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
	reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
	reg_w1(gspca_dev, 0x1189, scale);
	reg_w1(gspca_dev, 0x10e0, fmt);

	set_cmatrix(gspca_dev);
	set_gamma(gspca_dev);
	set_redblue(gspca_dev);
	set_gain(gspca_dev);
	set_exposure(gspca_dev);
	set_hvflip(gspca_dev);

2115
	reg_w1(gspca_dev, 0x1007, 0x20);
2116
	reg_w1(gspca_dev, 0x1061, 0x03);
2117 2118 2119 2120 2121 2122 2123 2124 2125

	/* if JPEG, prepare the compression quality update */
	if (mode & MODE_JPEG) {
		sd->pktsz = sd->npkt = 0;
		sd->nchg = 0;
		sd->work_thread =
			create_singlethread_workqueue(KBUILD_MODNAME);
	}

2126
	return gspca_dev->usb_err;
2127 2128 2129 2130
}

static void sd_stopN(struct gspca_dev *gspca_dev)
{
2131
	reg_w1(gspca_dev, 0x1007, 0x00);
2132
	reg_w1(gspca_dev, 0x1061, 0x01);
2133 2134
}

2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148
/* called on streamoff with alt==0 and on disconnect */
/* the usb_lock is held at entry - restore on exit */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *) gspca_dev;

	if (sd->work_thread != NULL) {
		mutex_unlock(&gspca_dev->usb_lock);
		destroy_workqueue(sd->work_thread);
		mutex_lock(&gspca_dev->usb_lock);
		sd->work_thread = NULL;
	}
}

2149
static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2150 2151
{
	struct sd *sd = (struct sd *) gspca_dev;
2152
	s16 new_exp;
2153 2154 2155 2156 2157 2158 2159

	/*
	 * some hardcoded values are present
	 * like those for maximal/minimal exposure
	 * and exposure steps
	 */
	if (avg_lum < MIN_AVG_LUM) {
2160
		if (sd->ctrls[EXPOSURE].val > 0x1770)
2161 2162
			return;

2163
		new_exp = sd->ctrls[EXPOSURE].val + sd->exposure_step;
2164 2165 2166 2167
		if (new_exp > 0x1770)
			new_exp = 0x1770;
		if (new_exp < 0x10)
			new_exp = 0x10;
2168
		sd->ctrls[EXPOSURE].val = new_exp;
2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179
		set_exposure(gspca_dev);

		sd->older_step = sd->old_step;
		sd->old_step = 1;

		if (sd->old_step ^ sd->older_step)
			sd->exposure_step /= 2;
		else
			sd->exposure_step += 2;
	}
	if (avg_lum > MAX_AVG_LUM) {
2180
		if (sd->ctrls[EXPOSURE].val < 0x10)
2181
			return;
2182
		new_exp = sd->ctrls[EXPOSURE].val - sd->exposure_step;
2183 2184 2185 2186
		if (new_exp > 0x1700)
			new_exp = 0x1770;
		if (new_exp < 0x10)
			new_exp = 0x10;
2187
		sd->ctrls[EXPOSURE].val = new_exp;
2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198
		set_exposure(gspca_dev);
		sd->older_step = sd->old_step;
		sd->old_step = 0;

		if (sd->old_step ^ sd->older_step)
			sd->exposure_step /= 2;
		else
			sd->exposure_step += 2;
	}
}

2199 2200 2201 2202 2203
static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
{
	struct sd *sd = (struct sd *) gspca_dev;

	if (avg_lum < MIN_AVG_LUM) {
2204 2205
		if (sd->ctrls[GAIN].val + 1 <= 28) {
			sd->ctrls[GAIN].val++;
2206 2207 2208 2209
			set_gain(gspca_dev);
		}
	}
	if (avg_lum > MAX_AVG_LUM) {
2210 2211
		if (sd->ctrls[GAIN].val > 0) {
			sd->ctrls[GAIN].val--;
2212 2213 2214 2215 2216 2217 2218 2219 2220 2221
			set_gain(gspca_dev);
		}
	}
}

static void sd_dqcallback(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *) gspca_dev;
	int avg_lum;

2222
	if (!sd->ctrls[AUTOGAIN].val)
2223 2224 2225 2226 2227 2228 2229 2230 2231
		return;

	avg_lum = atomic_read(&sd->avg_lum);
	if (sd->sensor == SENSOR_SOI968)
		do_autogain(gspca_dev, avg_lum);
	else
		do_autoexposure(gspca_dev, avg_lum);
}

2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244
/* JPEG quality update */
/* This function is executed from a work queue. */
static void qual_upd(struct work_struct *work)
{
	struct sd *sd = container_of(work, struct sd, work);
	struct gspca_dev *gspca_dev = &sd->gspca_dev;

	mutex_lock(&gspca_dev->usb_lock);
	PDEBUG(D_STREAM, "qual_upd %d%%", sd->ctrls[QUALITY].val);
	set_quality(gspca_dev);
	mutex_unlock(&gspca_dev->usb_lock);
}

2245
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2246 2247 2248 2249 2250
static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
			u8 *data,		/* interrupt packet */
			int len)		/* interrupt packet length */
{
	struct sd *sd = (struct sd *) gspca_dev;
2251

2252
	if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2253 2254 2255 2256 2257
		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
		input_sync(gspca_dev->input_dev);
		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
		input_sync(gspca_dev->input_dev);
		return 0;
2258
	}
2259
	return -EINVAL;
2260 2261 2262
}
#endif

2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306
/* check the JPEG compression */
static void transfer_check(struct gspca_dev *gspca_dev,
			u8 *data)
{
	struct sd *sd = (struct sd *) gspca_dev;
	int new_qual, r;

	new_qual = 0;

	/* if USB error, discard the frame and decrease the quality */
	if (data[6] & 0x08) {				/* USB FIFO full */
		gspca_dev->last_packet_type = DISCARD_PACKET;
		new_qual = -5;
	} else {

		/* else, compute the filling rate and a new JPEG quality */
		r = (sd->pktsz * 100) /
			(sd->npkt *
				gspca_dev->urb[0]->iso_frame_desc[0].length);
		if (r >= 85)
			new_qual = -3;
		else if (r < 75)
			new_qual = 2;
	}
	if (new_qual != 0) {
		sd->nchg += new_qual;
		if (sd->nchg < -6 || sd->nchg >= 12) {
			sd->nchg = 0;
			new_qual += sd->ctrls[QUALITY].val;
			if (new_qual < QUALITY_MIN)
				new_qual = QUALITY_MIN;
			else if (new_qual > QUALITY_MAX)
				new_qual = QUALITY_MAX;
			if (new_qual != sd->ctrls[QUALITY].val) {
				sd->ctrls[QUALITY].val = new_qual;
				queue_work(sd->work_thread, &sd->work);
			}
		}
	} else {
		sd->nchg = 0;
	}
	sd->pktsz = sd->npkt = 0;
}

2307 2308 2309 2310 2311
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;
2312
	int avg_lum, is_jpeg;
2313
	static u8 frame_header[] =
2314
		{0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96};
2315 2316

	is_jpeg = (sd->fmt & 0x03) == 0;
2317
	if (len >= 64 && memcmp(data, frame_header, 6) == 0) {
2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343
		avg_lum = ((data[35] >> 2) & 3) |
			   (data[20] << 2) |
			   (data[19] << 10);
		avg_lum += ((data[35] >> 4) & 3) |
			    (data[22] << 2) |
			    (data[21] << 10);
		avg_lum += ((data[35] >> 6) & 3) |
			    (data[24] << 2) |
			    (data[23] << 10);
		avg_lum += (data[36] & 3) |
			   (data[26] << 2) |
			   (data[25] << 10);
		avg_lum += ((data[36] >> 2) & 3) |
			    (data[28] << 2) |
			    (data[27] << 10);
		avg_lum += ((data[36] >> 4) & 3) |
			    (data[30] << 2) |
			    (data[29] << 10);
		avg_lum += ((data[36] >> 6) & 3) |
			    (data[32] << 2) |
			    (data[31] << 10);
		avg_lum += ((data[44] >> 4) & 3) |
			    (data[34] << 2) |
			    (data[33] << 10);
		avg_lum >>= 9;
		atomic_set(&sd->avg_lum, avg_lum);
2344

2345
		if (is_jpeg)
2346 2347
			transfer_check(gspca_dev, data);

2348
		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2349 2350 2351 2352
		len -= 64;
		if (len == 0)
			return;
		data += 64;
2353 2354
	}
	if (gspca_dev->last_packet_type == LAST_PACKET) {
2355
		if (is_jpeg) {
2356
			gspca_frame_add(gspca_dev, FIRST_PACKET,
2357
				sd->jpeg_hdr, JPEG_HDR_SZ);
2358
			gspca_frame_add(gspca_dev, INTER_PACKET,
2359 2360
				data, len);
		} else {
2361
			gspca_frame_add(gspca_dev, FIRST_PACKET,
2362 2363 2364
				data, len);
		}
	} else {
2365
		/* if JPEG, count the packets and their size */
2366
		if (is_jpeg) {
2367 2368 2369
			sd->npkt++;
			sd->pktsz += len;
		}
2370
		gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2371 2372 2373 2374 2375
	}
}

/* sub-driver description */
static const struct sd_desc sd_desc = {
2376
	.name = KBUILD_MODNAME,
2377 2378 2379 2380
	.ctrls = sd_ctrls,
	.nctrls = ARRAY_SIZE(sd_ctrls),
	.config = sd_config,
	.init = sd_init,
2381
	.isoc_init = sd_isoc_init,
2382 2383
	.start = sd_start,
	.stopN = sd_stopN,
2384
	.stop0 = sd_stop0,
2385
	.pkt_scan = sd_pkt_scan,
2386
#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2387 2388
	.int_pkt_scan = sd_int_pkt_scan,
#endif
2389
	.dq_callback = sd_dqcallback,
2390 2391 2392 2393 2394 2395 2396
#ifdef CONFIG_VIDEO_ADV_DEBUG
	.set_register = sd_dbg_s_register,
	.get_register = sd_dbg_g_register,
#endif
	.get_chip_ident = sd_chip_ident,
};

2397
#define SN9C20X(sensor, i2c_addr, flags) \
2398
	.driver_info =  ((flags & 0xff) << 16) \
2399 2400 2401
			| (SENSOR_ ## sensor << 8) \
			| (i2c_addr)

2402
static const struct usb_device_id device_table[] = {
2403 2404 2405
	{USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
	{USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, 0)},
	{USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2406
	{USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2407 2408 2409
	{USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
	{USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
					     (FLIP_DETECT | HAS_NO_BUTTON))},
2410 2411 2412 2413
	{USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
	{USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
	{USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
	{USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2414
	{USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)},
2415 2416 2417 2418
	{USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
	{USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
	{USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
	{USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2419
	{USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2420
	{USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2421 2422 2423 2424
	{USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
	{USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
	{USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
	{USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2425
	{USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, LED_REVERSE)},
2426
	{USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)},
2427 2428 2429 2430
	{USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
	{USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
	{USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
	{USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2431 2432
	{USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
	{USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2433 2434 2435 2436
	{USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
	{USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
	{USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
	{USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2437
	{USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452
	{USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
	{USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
	{}
};
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 = {
2453
	.name = KBUILD_MODNAME,
2454 2455
	.id_table = device_table,
	.probe = sd_probe,
2456
	.disconnect = gspca_disconnect,
2457 2458 2459 2460 2461 2462 2463
#ifdef CONFIG_PM
	.suspend = gspca_suspend,
	.resume = gspca_resume,
	.reset_resume = gspca_resume,
#endif
};

2464
module_usb_driver(sd_driver);