• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/media/video/gspca/
1/*
2 *		sonix sn9c102 (bayer) library
3 *		Copyright (C) 2003 2004 Michel Xhaard mxhaard@magic.fr
4 * Add Pas106 Stefano Mozzi (C) 2004
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/* Some documentation on known sonixb registers:
24
25Reg	Use
260x10	high nibble red gain low nibble blue gain
270x11	low nibble green gain
280x12	hstart
290x13	vstart
300x15	hsize (hsize = register-value * 16)
310x16	vsize (vsize = register-value * 16)
320x17	bit 0 toggle compression quality (according to sn9c102 driver)
330x18	bit 7 enables compression, bit 4-5 set image down scaling:
34	00 scale 1, 01 scale 1/2, 10, scale 1/4
350x19	high-nibble is sensor clock divider, changes exposure on sensors which
36	use a clock generated by the bridge. Some sensors have their own clock.
370x1c	auto_exposure area (for avg_lum) startx (startx = register-value * 32)
380x1d	auto_exposure area (for avg_lum) starty (starty = register-value * 32)
390x1e	auto_exposure area (for avg_lum) stopx (hsize = (0x1e - 0x1c) * 32)
400x1f	auto_exposure area (for avg_lum) stopy (vsize = (0x1f - 0x1d) * 32)
41*/
42
43#define MODULE_NAME "sonixb"
44
45#include <linux/input.h>
46#include "gspca.h"
47
48MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
49MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
50MODULE_LICENSE("GPL");
51
52/* specific webcam descriptor */
53struct sd {
54	struct gspca_dev gspca_dev;	/* !! must be the first item */
55	atomic_t avg_lum;
56	int prev_avg_lum;
57	int exp_too_low_cnt;
58	int exp_too_high_cnt;
59
60	unsigned short exposure;
61	unsigned char gain;
62	unsigned char brightness;
63	unsigned char autogain;
64	unsigned char autogain_ignore_frames;
65	unsigned char frames_to_drop;
66	unsigned char freq;		/* light freq filter setting */
67
68	__u8 bridge;			/* Type of bridge */
69#define BRIDGE_101 0
70#define BRIDGE_102 0 /* We make no difference between 101 and 102 */
71#define BRIDGE_103 1
72
73	__u8 sensor;			/* Type of image sensor chip */
74#define SENSOR_HV7131R 0
75#define SENSOR_OV6650 1
76#define SENSOR_OV7630 2
77#define SENSOR_PAS106 3
78#define SENSOR_PAS202 4
79#define SENSOR_TAS5110C 5
80#define SENSOR_TAS5110D 6
81#define SENSOR_TAS5130CXX 7
82	__u8 reg11;
83};
84
85typedef const __u8 sensor_init_t[8];
86
87struct sensor_data {
88	const __u8 *bridge_init[2];
89	int bridge_init_size[2];
90	sensor_init_t *sensor_init;
91	int sensor_init_size;
92	sensor_init_t *sensor_bridge_init[2];
93	int sensor_bridge_init_size[2];
94	int flags;
95	unsigned ctrl_dis;
96	__u8 sensor_addr;
97};
98
99/* sensor_data flags */
100#define F_GAIN 0x01		/* has gain */
101#define F_SIF  0x02		/* sif or vga */
102#define F_COARSE_EXPO 0x04	/* exposure control is coarse */
103
104/* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
105#define MODE_RAW 0x10		/* raw bayer mode */
106#define MODE_REDUCED_SIF 0x20	/* vga mode (320x240 / 160x120) on sif cam */
107
108/* ctrl_dis helper macros */
109#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << COARSE_EXPOSURE_IDX) | \
110		 (1 << AUTOGAIN_IDX))
111#define NO_FREQ (1 << FREQ_IDX)
112#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
113
114#define COMP2 0x8f
115#define COMP 0xc7		/* 0x87 //0x07 */
116#define COMP1 0xc9		/* 0x89 //0x09 */
117
118#define MCK_INIT 0x63
119#define MCK_INIT1 0x20
120
121#define SYS_CLK 0x04
122
123#define SENS(bridge_1, bridge_3, sensor, sensor_1, \
124	sensor_3, _flags, _ctrl_dis, _sensor_addr) \
125{ \
126	.bridge_init = { bridge_1, bridge_3 }, \
127	.bridge_init_size = { sizeof(bridge_1), sizeof(bridge_3) }, \
128	.sensor_init = sensor, \
129	.sensor_init_size = sizeof(sensor), \
130	.sensor_bridge_init = { sensor_1, sensor_3,}, \
131	.sensor_bridge_init_size = { sizeof(sensor_1), sizeof(sensor_3)}, \
132	.flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \
133}
134
135/* We calculate the autogain at the end of the transfer of a frame, at this
136   moment a frame with the old settings is being captured and transmitted. So
137   if we adjust the gain or exposure we must ignore atleast the next frame for
138   the new settings to come into effect before doing any other adjustments. */
139#define AUTOGAIN_IGNORE_FRAMES 1
140
141/* V4L2 controls supported by the driver */
142static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
143static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
144static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
145static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
146static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
147static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
148static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
149static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
150static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
151static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
152
153static const struct ctrl sd_ctrls[] = {
154#define BRIGHTNESS_IDX 0
155	{
156	    {
157		.id      = V4L2_CID_BRIGHTNESS,
158		.type    = V4L2_CTRL_TYPE_INTEGER,
159		.name    = "Brightness",
160		.minimum = 0,
161		.maximum = 255,
162		.step    = 1,
163#define BRIGHTNESS_DEF 127
164		.default_value = BRIGHTNESS_DEF,
165	    },
166	    .set = sd_setbrightness,
167	    .get = sd_getbrightness,
168	},
169#define GAIN_IDX 1
170	{
171	    {
172		.id      = V4L2_CID_GAIN,
173		.type    = V4L2_CTRL_TYPE_INTEGER,
174		.name    = "Gain",
175		.minimum = 0,
176		.maximum = 255,
177		.step    = 1,
178#define GAIN_DEF 127
179#define GAIN_KNEE 230
180		.default_value = GAIN_DEF,
181	    },
182	    .set = sd_setgain,
183	    .get = sd_getgain,
184	},
185#define EXPOSURE_IDX 2
186	{
187		{
188			.id = V4L2_CID_EXPOSURE,
189			.type = V4L2_CTRL_TYPE_INTEGER,
190			.name = "Exposure",
191#define EXPOSURE_DEF  66 /*  33 ms / 30 fps (except on PASXXX) */
192#define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */
193			.minimum = 0,
194			.maximum = 1023,
195			.step = 1,
196			.default_value = EXPOSURE_DEF,
197			.flags = 0,
198		},
199		.set = sd_setexposure,
200		.get = sd_getexposure,
201	},
202#define COARSE_EXPOSURE_IDX 3
203	{
204		{
205			.id = V4L2_CID_EXPOSURE,
206			.type = V4L2_CTRL_TYPE_INTEGER,
207			.name = "Exposure",
208#define COARSE_EXPOSURE_DEF  2 /* 30 fps */
209			.minimum = 2,
210			.maximum = 15,
211			.step = 1,
212			.default_value = COARSE_EXPOSURE_DEF,
213			.flags = 0,
214		},
215		.set = sd_setexposure,
216		.get = sd_getexposure,
217	},
218#define AUTOGAIN_IDX 4
219	{
220		{
221			.id = V4L2_CID_AUTOGAIN,
222			.type = V4L2_CTRL_TYPE_BOOLEAN,
223			.name = "Automatic Gain (and Exposure)",
224			.minimum = 0,
225			.maximum = 1,
226			.step = 1,
227#define AUTOGAIN_DEF 1
228			.default_value = AUTOGAIN_DEF,
229			.flags = 0,
230		},
231		.set = sd_setautogain,
232		.get = sd_getautogain,
233	},
234#define FREQ_IDX 5
235	{
236		{
237			.id	 = V4L2_CID_POWER_LINE_FREQUENCY,
238			.type    = V4L2_CTRL_TYPE_MENU,
239			.name    = "Light frequency filter",
240			.minimum = 0,
241			.maximum = 2,	/* 0: 0, 1: 50Hz, 2:60Hz */
242			.step    = 1,
243#define FREQ_DEF 0
244			.default_value = FREQ_DEF,
245		},
246		.set = sd_setfreq,
247		.get = sd_getfreq,
248	},
249};
250
251static const struct v4l2_pix_format vga_mode[] = {
252	{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
253		.bytesperline = 160,
254		.sizeimage = 160 * 120,
255		.colorspace = V4L2_COLORSPACE_SRGB,
256		.priv = 2 | MODE_RAW},
257	{160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
258		.bytesperline = 160,
259		.sizeimage = 160 * 120 * 5 / 4,
260		.colorspace = V4L2_COLORSPACE_SRGB,
261		.priv = 2},
262	{320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
263		.bytesperline = 320,
264		.sizeimage = 320 * 240 * 5 / 4,
265		.colorspace = V4L2_COLORSPACE_SRGB,
266		.priv = 1},
267	{640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
268		.bytesperline = 640,
269		.sizeimage = 640 * 480 * 5 / 4,
270		.colorspace = V4L2_COLORSPACE_SRGB,
271		.priv = 0},
272};
273static const struct v4l2_pix_format sif_mode[] = {
274	{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
275		.bytesperline = 160,
276		.sizeimage = 160 * 120,
277		.colorspace = V4L2_COLORSPACE_SRGB,
278		.priv = 1 | MODE_RAW | MODE_REDUCED_SIF},
279	{160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
280		.bytesperline = 160,
281		.sizeimage = 160 * 120 * 5 / 4,
282		.colorspace = V4L2_COLORSPACE_SRGB,
283		.priv = 1 | MODE_REDUCED_SIF},
284	{176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
285		.bytesperline = 176,
286		.sizeimage = 176 * 144,
287		.colorspace = V4L2_COLORSPACE_SRGB,
288		.priv = 1 | MODE_RAW},
289	{176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
290		.bytesperline = 176,
291		.sizeimage = 176 * 144 * 5 / 4,
292		.colorspace = V4L2_COLORSPACE_SRGB,
293		.priv = 1},
294	{320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
295		.bytesperline = 320,
296		.sizeimage = 320 * 240 * 5 / 4,
297		.colorspace = V4L2_COLORSPACE_SRGB,
298		.priv = 0 | MODE_REDUCED_SIF},
299	{352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
300		.bytesperline = 352,
301		.sizeimage = 352 * 288 * 5 / 4,
302		.colorspace = V4L2_COLORSPACE_SRGB,
303		.priv = 0},
304};
305
306static const __u8 initHv7131[] = {
307	0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
308	0x00, 0x00,
309	0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
310	0x28, 0x1e, 0x60, 0x8a, 0x20,
311	0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
312};
313static const __u8 hv7131_sensor_init[][8] = {
314	{0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
315	{0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
316	{0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
317	{0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
318	{0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
319};
320static const __u8 initOv6650[] = {
321	0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
322	0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
323	0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
324	0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07
325};
326static const __u8 ov6650_sensor_init[][8] =
327{
328	/* Bright, contrast, etc are set through SCBB interface.
329	 * AVCAP on win2 do not send any data on this 	controls. */
330	/* Anyway, some registers appears to alter bright and constrat */
331
332	/* Reset sensor */
333	{0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
334	/* Set clock register 0x11 low nibble is clock divider */
335	{0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
336	/* Next some unknown stuff */
337	{0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
338/*	{0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
339		 * THIS SET GREEN SCREEN
340		 * (pixels could be innverted in decode kind of "brg",
341		 * but blue wont be there. Avoid this data ... */
342	{0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
343	{0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
344	{0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10},
345	/* Enable rgb brightness control */
346	{0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
347	/* HDG: Note windows uses the line below, which sets both register 0x60
348	   and 0x61 I believe these registers of the ov6650 are identical as
349	   those of the ov7630, because if this is true the windows settings
350	   add a bit additional red gain and a lot additional blue gain, which
351	   matches my findings that the windows settings make blue much too
352	   blue and red a little too red.
353	{0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */
354	/* Some more unknown stuff */
355	{0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
356	{0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
357};
358
359static const __u8 initOv7630[] = {
360	0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,	/* r01 .. r08 */
361	0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* r09 .. r10 */
362	0x00, 0x01, 0x01, 0x0a,				/* r11 .. r14 */
363	0x28, 0x1e,			/* H & V sizes     r15 .. r16 */
364	0x68, COMP2, MCK_INIT1,				/* r17 .. r19 */
365	0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c		/* r1a .. r1f */
366};
367static const __u8 initOv7630_3[] = {
368	0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80,	/* r01 .. r08 */
369	0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* r09 .. r10 */
370	0x00, 0x02, 0x01, 0x0a,				/* r11 .. r14 */
371	0x28, 0x1e,			/* H & V sizes     r15 .. r16 */
372	0x68, 0x8f, MCK_INIT1,				/* r17 .. r19 */
373	0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00,	/* r1a .. r20 */
374	0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
375	0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff  /* r29 .. r30 */
376};
377static const __u8 ov7630_sensor_init[][8] = {
378	{0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
379	{0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
380/*	{0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10},	   jfm */
381	{0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10},	/* jfm */
382	{0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
383	{0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
384	{0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
385	{0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
386	{0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
387	{0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
388	{0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
389	{0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
390/*	{0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10},	 * jfm */
391	{0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
392	{0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
393	{0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
394	{0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
395	{0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
396	{0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
397};
398
399static const __u8 ov7630_sensor_init_3[][8] = {
400	{0xa0, 0x21, 0x13, 0x80, 0x00,	0x00, 0x00, 0x10},
401};
402
403static const __u8 initPas106[] = {
404	0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
405	0x00, 0x00,
406	0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
407	0x16, 0x12, 0x24, COMP1, MCK_INIT1,
408	0x18, 0x10, 0x02, 0x02, 0x09, 0x07
409};
410/* compression 0x86 mckinit1 0x2b */
411
412/* "Known" PAS106B registers:
413  0x02 clock divider
414  0x03 Variable framerate bits 4-11
415  0x04 Var framerate bits 0-3, one must leave the 4 msb's at 0 !!
416       The variable framerate control must never be set lower then 300,
417       which sets the framerate at 90 / reg02, otherwise vsync is lost.
418  0x05 Shutter Time Line Offset, this can be used as an exposure control:
419       0 = use full frame time, 255 = no exposure at all
420       Note this may never be larger then "var-framerate control" / 2 - 2.
421       When var-framerate control is < 514, no exposure is reached at the max
422       allowed value for the framerate control value, rather then at 255.
423  0x06 Shutter Time Pixel Offset, like reg05 this influences exposure, but
424       only a very little bit, leave at 0xcd
425  0x07 offset sign bit (bit0 1 > negative offset)
426  0x08 offset
427  0x09 Blue Gain
428  0x0a Green1 Gain
429  0x0b Green2 Gain
430  0x0c Red Gain
431  0x0e Global gain
432  0x13 Write 1 to commit settings to sensor
433*/
434
435static const __u8 pas106_sensor_init[][8] = {
436	/* Pixel Clock Divider 6 */
437	{ 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
438	/* Frame Time MSB (also seen as 0x12) */
439	{ 0xa1, 0x40, 0x03, 0x13, 0x00, 0x00, 0x00, 0x14 },
440	/* Frame Time LSB (also seen as 0x05) */
441	{ 0xa1, 0x40, 0x04, 0x06, 0x00, 0x00, 0x00, 0x14 },
442	/* Shutter Time Line Offset (also seen as 0x6d) */
443	{ 0xa1, 0x40, 0x05, 0x65, 0x00, 0x00, 0x00, 0x14 },
444	/* Shutter Time Pixel Offset (also seen as 0xb1) */
445	{ 0xa1, 0x40, 0x06, 0xcd, 0x00, 0x00, 0x00, 0x14 },
446	/* Black Level Subtract Sign (also seen 0x00) */
447	{ 0xa1, 0x40, 0x07, 0xc1, 0x00, 0x00, 0x00, 0x14 },
448	/* Black Level Subtract Level (also seen 0x01) */
449	{ 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
450	{ 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
451	/* Color Gain B Pixel 5 a */
452	{ 0xa1, 0x40, 0x09, 0x05, 0x00, 0x00, 0x00, 0x14 },
453	/* Color Gain G1 Pixel 1 5 */
454	{ 0xa1, 0x40, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x14 },
455	/* Color Gain G2 Pixel 1 0 5 */
456	{ 0xa1, 0x40, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x14 },
457	/* Color Gain R Pixel 3 1 */
458	{ 0xa1, 0x40, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x14 },
459	/* Color GainH  Pixel */
460	{ 0xa1, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x14 },
461	/* Global Gain */
462	{ 0xa1, 0x40, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x14 },
463	/* Contrast */
464	{ 0xa1, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x14 },
465	/* H&V synchro polarity */
466	{ 0xa1, 0x40, 0x10, 0x06, 0x00, 0x00, 0x00, 0x14 },
467	/* ?default */
468	{ 0xa1, 0x40, 0x11, 0x06, 0x00, 0x00, 0x00, 0x14 },
469	/* DAC scale */
470	{ 0xa1, 0x40, 0x12, 0x06, 0x00, 0x00, 0x00, 0x14 },
471	/* ?default */
472	{ 0xa1, 0x40, 0x14, 0x02, 0x00, 0x00, 0x00, 0x14 },
473	/* Validate Settings */
474	{ 0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14 },
475};
476
477static const __u8 initPas202[] = {
478	0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
479	0x00, 0x00,
480	0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
481	0x28, 0x1e, 0x20, 0x89, 0x20,
482	0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
483};
484
485/* "Known" PAS202BCB registers:
486  0x02 clock divider
487  0x04 Variable framerate bits 6-11 (*)
488  0x05 Var framerate  bits 0-5, one must leave the 2 msb's at 0 !!
489  0x07 Blue Gain
490  0x08 Green Gain
491  0x09 Red Gain
492  0x0b offset sign bit (bit0 1 > negative offset)
493  0x0c offset
494  0x0e Unknown image is slightly brighter when bit 0 is 0, if reg0f is 0 too,
495       leave at 1 otherwise we get a jump in our exposure control
496  0x0f Exposure 0-255, 0 = use full frame time, 255 = no exposure at all
497  0x10 Master gain 0 - 31
498  0x11 write 1 to apply changes
499  (*) The variable framerate control must never be set lower then 500
500      which sets the framerate at 30 / reg02, otherwise vsync is lost.
501*/
502static const __u8 pas202_sensor_init[][8] = {
503	/* Set the clock divider to 4 -> 30 / 4 = 7.5 fps, we would like
504	   to set it lower, but for some reason the bridge starts missing
505	   vsync's then */
506	{0xa0, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x10},
507	{0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
508	{0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
509	{0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x01, 0x32, 0x10},
510	{0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
511	{0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
512	{0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
513	{0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
514	{0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
515	{0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
516};
517
518static const __u8 initTas5110c[] = {
519	0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
520	0x00, 0x00,
521	0x00, 0x00, 0x00, 0x45, 0x09, 0x0a,
522	0x16, 0x12, 0x60, 0x86, 0x2b,
523	0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
524};
525/* Same as above, except a different hstart */
526static const __u8 initTas5110d[] = {
527	0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
528	0x00, 0x00,
529	0x00, 0x00, 0x00, 0x41, 0x09, 0x0a,
530	0x16, 0x12, 0x60, 0x86, 0x2b,
531	0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
532};
533static const __u8 tas5110_sensor_init[][8] = {
534	{0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
535	{0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
536	{0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
537};
538
539static const __u8 initTas5130[] = {
540	0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
541	0x00, 0x00,
542	0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a,
543	0x28, 0x1e, 0x60, COMP, MCK_INIT,
544	0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
545};
546static const __u8 tas5130_sensor_init[][8] = {
547/* 	{0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
548					* shutter 0x47 short exposure? */
549	{0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
550					/* shutter 0x01 long exposure */
551	{0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
552};
553
554static struct sensor_data sensor_data[] = {
555SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0),
556SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
557SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
558	F_GAIN, 0, 0x21),
559SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_GAIN|F_SIF, NO_FREQ,
560	0),
561SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, F_GAIN,
562	NO_FREQ, 0),
563SENS(initTas5110c, NULL, tas5110_sensor_init, NULL, NULL,
564	F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0),
565SENS(initTas5110d, NULL, tas5110_sensor_init, NULL, NULL,
566	F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0),
567SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
568	0),
569};
570
571/* get one byte in gspca_dev->usb_buf */
572static void reg_r(struct gspca_dev *gspca_dev,
573		  __u16 value)
574{
575	usb_control_msg(gspca_dev->dev,
576			usb_rcvctrlpipe(gspca_dev->dev, 0),
577			0,			/* request */
578			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
579			value,
580			0,			/* index */
581			gspca_dev->usb_buf, 1,
582			500);
583}
584
585static void reg_w(struct gspca_dev *gspca_dev,
586		  __u16 value,
587		  const __u8 *buffer,
588		  int len)
589{
590#ifdef GSPCA_DEBUG
591	if (len > USB_BUF_SZ) {
592		PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
593		return;
594	}
595#endif
596	memcpy(gspca_dev->usb_buf, buffer, len);
597	usb_control_msg(gspca_dev->dev,
598			usb_sndctrlpipe(gspca_dev->dev, 0),
599			0x08,			/* request */
600			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
601			value,
602			0,			/* index */
603			gspca_dev->usb_buf, len,
604			500);
605}
606
607static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
608{
609	int retry = 60;
610
611	/* is i2c ready */
612	reg_w(gspca_dev, 0x08, buffer, 8);
613	while (retry--) {
614		msleep(10);
615		reg_r(gspca_dev, 0x08);
616		if (gspca_dev->usb_buf[0] & 0x04) {
617			if (gspca_dev->usb_buf[0] & 0x08)
618				return -1;
619			return 0;
620		}
621	}
622	return -1;
623}
624
625static void i2c_w_vector(struct gspca_dev *gspca_dev,
626			const __u8 buffer[][8], int len)
627{
628	for (;;) {
629		reg_w(gspca_dev, 0x08, *buffer, 8);
630		len -= 8;
631		if (len <= 0)
632			break;
633		buffer++;
634	}
635}
636
637static void setbrightness(struct gspca_dev *gspca_dev)
638{
639	struct sd *sd = (struct sd *) gspca_dev;
640	__u8 value;
641
642	switch (sd->sensor) {
643	case  SENSOR_OV6650:
644	case  SENSOR_OV7630: {
645		__u8 i2cOV[] =
646			{0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
647
648		/* change reg 0x06 */
649		i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
650		i2cOV[3] = sd->brightness;
651		if (i2c_w(gspca_dev, i2cOV) < 0)
652			goto err;
653		break;
654	    }
655	case SENSOR_PAS106:
656	case SENSOR_PAS202: {
657		__u8 i2cpbright[] =
658			{0xb0, 0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x16};
659		__u8 i2cpdoit[] =
660			{0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
661
662		/* PAS106 uses reg 7 and 8 instead of b and c */
663		if (sd->sensor == SENSOR_PAS106) {
664			i2cpbright[2] = 7;
665			i2cpdoit[2] = 0x13;
666		}
667
668		if (sd->brightness < 127) {
669			/* change reg 0x0b, signreg */
670			i2cpbright[3] = 0x01;
671			/* set reg 0x0c, offset */
672			i2cpbright[4] = 127 - sd->brightness;
673		} else
674			i2cpbright[4] = sd->brightness - 127;
675
676		if (i2c_w(gspca_dev, i2cpbright) < 0)
677			goto err;
678		if (i2c_w(gspca_dev, i2cpdoit) < 0)
679			goto err;
680		break;
681	    }
682	case SENSOR_TAS5130CXX: {
683		__u8 i2c[] =
684			{0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
685
686		value = 0xff - sd->brightness;
687		i2c[4] = value;
688		PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
689		if (i2c_w(gspca_dev, i2c) < 0)
690			goto err;
691		break;
692	    }
693	}
694	return;
695err:
696	PDEBUG(D_ERR, "i2c error brightness");
697}
698
699static void setsensorgain(struct gspca_dev *gspca_dev)
700{
701	struct sd *sd = (struct sd *) gspca_dev;
702	unsigned char gain = sd->gain;
703
704	switch (sd->sensor) {
705
706	case SENSOR_TAS5110C:
707	case SENSOR_TAS5110D: {
708		__u8 i2c[] =
709			{0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
710
711		i2c[4] = 255 - gain;
712		if (i2c_w(gspca_dev, i2c) < 0)
713			goto err;
714		break;
715	    }
716
717	case SENSOR_OV6650:
718		gain >>= 1;
719		/* fall thru */
720	case SENSOR_OV7630: {
721		__u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
722
723		i2c[1] = sensor_data[sd->sensor].sensor_addr;
724		i2c[3] = gain >> 2;
725		if (i2c_w(gspca_dev, i2c) < 0)
726			goto err;
727		break;
728	    }
729	case SENSOR_PAS106:
730	case SENSOR_PAS202: {
731		__u8 i2cpgain[] =
732			{0xa0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15};
733		__u8 i2cpcolorgain[] =
734			{0xc0, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x15};
735		__u8 i2cpdoit[] =
736			{0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
737
738		/* PAS106 uses different regs (and has split green gains) */
739		if (sd->sensor == SENSOR_PAS106) {
740			i2cpgain[2] = 0x0e;
741			i2cpcolorgain[0] = 0xd0;
742			i2cpcolorgain[2] = 0x09;
743			i2cpdoit[2] = 0x13;
744		}
745
746		i2cpgain[3] = sd->gain >> 3;
747		i2cpcolorgain[3] = sd->gain >> 4;
748		i2cpcolorgain[4] = sd->gain >> 4;
749		i2cpcolorgain[5] = sd->gain >> 4;
750		i2cpcolorgain[6] = sd->gain >> 4;
751
752		if (i2c_w(gspca_dev, i2cpgain) < 0)
753			goto err;
754		if (i2c_w(gspca_dev, i2cpcolorgain) < 0)
755			goto err;
756		if (i2c_w(gspca_dev, i2cpdoit) < 0)
757			goto err;
758		break;
759	    }
760	}
761	return;
762err:
763	PDEBUG(D_ERR, "i2c error gain");
764}
765
766static void setgain(struct gspca_dev *gspca_dev)
767{
768	struct sd *sd = (struct sd *) gspca_dev;
769	__u8 gain;
770	__u8 buf[2] = { 0, 0 };
771
772	if (sensor_data[sd->sensor].flags & F_GAIN) {
773		/* Use the sensor gain to do the actual gain */
774		setsensorgain(gspca_dev);
775		return;
776	}
777
778	gain = sd->gain >> 4;
779
780	/* red and blue gain */
781	buf[0] = gain << 4 | gain;
782	/* green gain */
783	buf[1] = gain;
784	reg_w(gspca_dev, 0x10, buf, 2);
785}
786
787static void setexposure(struct gspca_dev *gspca_dev)
788{
789	struct sd *sd = (struct sd *) gspca_dev;
790
791	switch (sd->sensor) {
792	case SENSOR_TAS5110C:
793	case SENSOR_TAS5110D: {
794		/* register 19's high nibble contains the sn9c10x clock divider
795		   The high nibble configures the no fps according to the
796		   formula: 60 / high_nibble. With a maximum of 30 fps */
797		__u8 reg = sd->exposure;
798		reg = (reg << 4) | 0x0b;
799		reg_w(gspca_dev, 0x19, &reg, 1);
800		break;
801	    }
802	case SENSOR_OV6650:
803	case SENSOR_OV7630: {
804		/* The ov6650 / ov7630 have 2 registers which both influence
805		   exposure, register 11, whose low nibble sets the nr off fps
806		   according to: fps = 30 / (low_nibble + 1)
807
808		   The fps configures the maximum exposure setting, but it is
809		   possible to use less exposure then what the fps maximum
810		   allows by setting register 10. register 10 configures the
811		   actual exposure as quotient of the full exposure, with 0
812		   being no exposure at all (not very usefull) and reg10_max
813		   being max exposure possible at that framerate.
814
815		   The code maps our 0 - 510 ms exposure ctrl to these 2
816		   registers, trying to keep fps as high as possible.
817		*/
818		__u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
819		int reg10, reg11, reg10_max;
820
821		/* ov6645 datasheet says reg10_max is 9a, but that uses
822		   tline * 2 * reg10 as formula for calculating texpo, the
823		   ov6650 probably uses the same formula as the 7730 which uses
824		   tline * 4 * reg10, which explains why the reg10max we've
825		   found experimentally for the ov6650 is exactly half that of
826		   the ov6645. The ov7630 datasheet says the max is 0x41. */
827		if (sd->sensor == SENSOR_OV6650) {
828			reg10_max = 0x4d;
829			i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
830		} else
831			reg10_max = 0x41;
832
833		reg11 = (15 * sd->exposure + 999) / 1000;
834		if (reg11 < 1)
835			reg11 = 1;
836		else if (reg11 > 16)
837			reg11 = 16;
838
839		/* In 640x480, if the reg11 has less than 4, the image is
840		   unstable (the bridge goes into a higher compression mode
841		   which we have not reverse engineered yet). */
842		if (gspca_dev->width == 640 && reg11 < 4)
843			reg11 = 4;
844
845		/* frame exposure time in ms = 1000 * reg11 / 30    ->
846		reg10 = (sd->exposure / 2) * reg10_max / (1000 * reg11 / 30) */
847		reg10 = (sd->exposure * 15 * reg10_max) / (1000 * reg11);
848
849		/* Don't allow this to get below 10 when using autogain, the
850		   steps become very large (relatively) when below 10 causing
851		   the image to oscilate from much too dark, to much too bright
852		   and back again. */
853		if (sd->autogain && reg10 < 10)
854			reg10 = 10;
855		else if (reg10 > reg10_max)
856			reg10 = reg10_max;
857
858		/* Write reg 10 and reg11 low nibble */
859		i2c[1] = sensor_data[sd->sensor].sensor_addr;
860		i2c[3] = reg10;
861		i2c[4] |= reg11 - 1;
862
863		/* If register 11 didn't change, don't change it */
864		if (sd->reg11 == reg11 )
865			i2c[0] = 0xa0;
866
867		if (i2c_w(gspca_dev, i2c) == 0)
868			sd->reg11 = reg11;
869		else
870			goto err;
871		break;
872	    }
873	case SENSOR_PAS202: {
874		__u8 i2cpframerate[] =
875			{0xb0, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x16};
876		__u8 i2cpexpo[] =
877			{0xa0, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x16};
878		const __u8 i2cpdoit[] =
879			{0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
880		int framerate_ctrl;
881
882		/* The exposure knee for the autogain algorithm is 200
883		   (100 ms / 10 fps on other sensors), for values below this
884		   use the control for setting the partial frame expose time,
885		   above that use variable framerate. This way we run at max
886		   framerate (640x480@7.5 fps, 320x240@10fps) until the knee
887		   is reached. Using the variable framerate control above 200
888		   is better then playing around with both clockdiv + partial
889		   frame exposure times (like we are doing with the ov chips),
890		   as that sometimes leads to jumps in the exposure control,
891		   which are bad for auto exposure. */
892		if (sd->exposure < 200) {
893			i2cpexpo[3] = 255 - (sd->exposure * 255) / 200;
894			framerate_ctrl = 500;
895		} else {
896			/* The PAS202's exposure control goes from 0 - 4095,
897			   but anything below 500 causes vsync issues, so scale
898			   our 200-1023 to 500-4095 */
899			framerate_ctrl = (sd->exposure - 200) * 1000 / 229 +
900					 500;
901		}
902
903		i2cpframerate[3] = framerate_ctrl >> 6;
904		i2cpframerate[4] = framerate_ctrl & 0x3f;
905		if (i2c_w(gspca_dev, i2cpframerate) < 0)
906			goto err;
907		if (i2c_w(gspca_dev, i2cpexpo) < 0)
908			goto err;
909		if (i2c_w(gspca_dev, i2cpdoit) < 0)
910			goto err;
911		break;
912	    }
913	case SENSOR_PAS106: {
914		__u8 i2cpframerate[] =
915			{0xb1, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x14};
916		__u8 i2cpexpo[] =
917			{0xa1, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x14};
918		const __u8 i2cpdoit[] =
919			{0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14};
920		int framerate_ctrl;
921
922		/* For values below 150 use partial frame exposure, above
923		   that use framerate ctrl */
924		if (sd->exposure < 150) {
925			i2cpexpo[3] = 150 - sd->exposure;
926			framerate_ctrl = 300;
927		} else {
928			/* The PAS106's exposure control goes from 0 - 4095,
929			   but anything below 300 causes vsync issues, so scale
930			   our 150-1023 to 300-4095 */
931			framerate_ctrl = (sd->exposure - 150) * 1000 / 230 +
932					 300;
933		}
934
935		i2cpframerate[3] = framerate_ctrl >> 4;
936		i2cpframerate[4] = framerate_ctrl & 0x0f;
937		if (i2c_w(gspca_dev, i2cpframerate) < 0)
938			goto err;
939		if (i2c_w(gspca_dev, i2cpexpo) < 0)
940			goto err;
941		if (i2c_w(gspca_dev, i2cpdoit) < 0)
942			goto err;
943		break;
944	    }
945	}
946	return;
947err:
948	PDEBUG(D_ERR, "i2c error exposure");
949}
950
951static void setfreq(struct gspca_dev *gspca_dev)
952{
953	struct sd *sd = (struct sd *) gspca_dev;
954
955	switch (sd->sensor) {
956	case SENSOR_OV6650:
957	case SENSOR_OV7630: {
958		/* Framerate adjust register for artificial light 50 hz flicker
959		   compensation, for the ov6650 this is identical to ov6630
960		   0x2b register, see ov6630 datasheet.
961		   0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
962		__u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
963		switch (sd->freq) {
964		default:
965/*		case 0:			 * no filter*/
966/*		case 2:			 * 60 hz */
967			i2c[3] = 0;
968			break;
969		case 1:			/* 50 hz */
970			i2c[3] = (sd->sensor == SENSOR_OV6650)
971					? 0x4f : 0x8a;
972			break;
973		}
974		i2c[1] = sensor_data[sd->sensor].sensor_addr;
975		if (i2c_w(gspca_dev, i2c) < 0)
976			PDEBUG(D_ERR, "i2c error setfreq");
977		break;
978	    }
979	}
980}
981
982#include "coarse_expo_autogain.h"
983
984static void do_autogain(struct gspca_dev *gspca_dev)
985{
986	int deadzone, desired_avg_lum, result;
987	struct sd *sd = (struct sd *) gspca_dev;
988	int avg_lum = atomic_read(&sd->avg_lum);
989
990	if (avg_lum == -1 || !sd->autogain)
991		return;
992
993	if (sd->autogain_ignore_frames > 0) {
994		sd->autogain_ignore_frames--;
995		return;
996	}
997
998	/* SIF / VGA sensors have a different autoexposure area and thus
999	   different avg_lum values for the same picture brightness */
1000	if (sensor_data[sd->sensor].flags & F_SIF) {
1001		deadzone = 500;
1002		/* SIF sensors tend to overexpose, so keep this small */
1003		desired_avg_lum = 5000;
1004	} else {
1005		deadzone = 1500;
1006		desired_avg_lum = 18000;
1007	}
1008
1009	if (sensor_data[sd->sensor].flags & F_COARSE_EXPO)
1010		result = gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
1011				sd->brightness * desired_avg_lum / 127,
1012				deadzone);
1013	else
1014		result = gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
1015				sd->brightness * desired_avg_lum / 127,
1016				deadzone, GAIN_KNEE, EXPOSURE_KNEE);
1017
1018	if (result) {
1019		PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d",
1020			(int)sd->gain, (int)sd->exposure);
1021		sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1022	}
1023}
1024
1025/* this function is called at probe time */
1026static int sd_config(struct gspca_dev *gspca_dev,
1027			const struct usb_device_id *id)
1028{
1029	struct sd *sd = (struct sd *) gspca_dev;
1030	struct cam *cam;
1031
1032	reg_r(gspca_dev, 0x00);
1033	if (gspca_dev->usb_buf[0] != 0x10)
1034		return -ENODEV;
1035
1036	/* copy the webcam info from the device id */
1037	sd->sensor = id->driver_info >> 8;
1038	sd->bridge = id->driver_info & 0xff;
1039	gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
1040
1041	cam = &gspca_dev->cam;
1042	if (!(sensor_data[sd->sensor].flags & F_SIF)) {
1043		cam->cam_mode = vga_mode;
1044		cam->nmodes = ARRAY_SIZE(vga_mode);
1045	} else {
1046		cam->cam_mode = sif_mode;
1047		cam->nmodes = ARRAY_SIZE(sif_mode);
1048	}
1049	cam->npkt = 36;			/* 36 packets per ISOC message */
1050
1051	sd->brightness = BRIGHTNESS_DEF;
1052	sd->gain = GAIN_DEF;
1053	if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) {
1054		sd->exposure = COARSE_EXPOSURE_DEF;
1055		gspca_dev->ctrl_dis |= (1 << EXPOSURE_IDX);
1056	} else {
1057		sd->exposure = EXPOSURE_DEF;
1058		gspca_dev->ctrl_dis |= (1 << COARSE_EXPOSURE_IDX);
1059	}
1060	if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1061		sd->autogain = 0; /* Disable do_autogain callback */
1062	else
1063		sd->autogain = AUTOGAIN_DEF;
1064	sd->freq = FREQ_DEF;
1065
1066	return 0;
1067}
1068
1069/* this function is called at probe and resume time */
1070static int sd_init(struct gspca_dev *gspca_dev)
1071{
1072	const __u8 stop = 0x09; /* Disable stream turn of LED */
1073
1074	reg_w(gspca_dev, 0x01, &stop, 1);
1075
1076	return 0;
1077}
1078
1079/* -- start the camera -- */
1080static int sd_start(struct gspca_dev *gspca_dev)
1081{
1082	struct sd *sd = (struct sd *) gspca_dev;
1083	struct cam *cam = &gspca_dev->cam;
1084	int mode, l;
1085	const __u8 *sn9c10x;
1086	__u8 reg12_19[8];
1087
1088	mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
1089	sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge];
1090	l = sensor_data[sd->sensor].bridge_init_size[sd->bridge];
1091	memcpy(reg12_19, &sn9c10x[0x12 - 1], 8);
1092	reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4);
1093	/* Special cases where reg 17 and or 19 value depends on mode */
1094	switch (sd->sensor) {
1095	case SENSOR_TAS5130CXX:
1096		/* probably not mode specific at all most likely the upper
1097		   nibble of 0x19 is exposure (clock divider) just as with
1098		   the tas5110, we need someone to test this. */
1099		reg12_19[7] = mode ? 0x23 : 0x43;
1100		break;
1101	}
1102	/* Disable compression when the raw bayer format has been selected */
1103	if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
1104		reg12_19[6] &= ~0x80;
1105
1106	/* Vga mode emulation on SIF sensor? */
1107	if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
1108		reg12_19[0] += 16; /* 0x12: hstart adjust */
1109		reg12_19[1] += 24; /* 0x13: vstart adjust */
1110		reg12_19[3] = 320 / 16; /* 0x15: hsize */
1111		reg12_19[4] = 240 / 16; /* 0x16: vsize */
1112	}
1113
1114	/* reg 0x01 bit 2 video transfert on */
1115	reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
1116	/* reg 0x17 SensorClk enable inv Clk 0x60 */
1117	reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
1118	/* Set the registers from the template */
1119	reg_w(gspca_dev, 0x01, sn9c10x, l);
1120
1121	/* Init the sensor */
1122	i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
1123			sensor_data[sd->sensor].sensor_init_size);
1124	if (sensor_data[sd->sensor].sensor_bridge_init[sd->bridge])
1125		i2c_w_vector(gspca_dev,
1126			sensor_data[sd->sensor].sensor_bridge_init[sd->bridge],
1127			sensor_data[sd->sensor].sensor_bridge_init_size[
1128				sd->bridge]);
1129
1130	/* Mode specific sensor setup */
1131	switch (sd->sensor) {
1132	case SENSOR_PAS202: {
1133		const __u8 i2cpclockdiv[] =
1134			{0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10};
1135		/* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */
1136		if (mode)
1137			i2c_w(gspca_dev, i2cpclockdiv);
1138	    }
1139	}
1140	/* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
1141	reg_w(gspca_dev, 0x15, &reg12_19[3], 2);
1142	/* compression register */
1143	reg_w(gspca_dev, 0x18, &reg12_19[6], 1);
1144	/* H_start */
1145	reg_w(gspca_dev, 0x12, &reg12_19[0], 1);
1146	/* V_START */
1147	reg_w(gspca_dev, 0x13, &reg12_19[1], 1);
1148	/* reset 0x17 SensorClk enable inv Clk 0x60 */
1149	reg_w(gspca_dev, 0x17, &reg12_19[5], 1);
1150	/*MCKSIZE ->3 */
1151	reg_w(gspca_dev, 0x19, &reg12_19[7], 1);
1152	/* AE_STRX AE_STRY AE_ENDX AE_ENDY */
1153	reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
1154	/* Enable video transfert */
1155	reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
1156	/* Compression */
1157	reg_w(gspca_dev, 0x18, &reg12_19[6], 2);
1158	msleep(20);
1159
1160	sd->reg11 = -1;
1161
1162	setgain(gspca_dev);
1163	setbrightness(gspca_dev);
1164	setexposure(gspca_dev);
1165	setfreq(gspca_dev);
1166
1167	sd->frames_to_drop = 0;
1168	sd->autogain_ignore_frames = 0;
1169	sd->exp_too_high_cnt = 0;
1170	sd->exp_too_low_cnt = 0;
1171	atomic_set(&sd->avg_lum, -1);
1172	return 0;
1173}
1174
1175static void sd_stopN(struct gspca_dev *gspca_dev)
1176{
1177	sd_init(gspca_dev);
1178}
1179
1180static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1181			u8 *data,			/* isoc packet */
1182			int len)			/* iso packet length */
1183{
1184	int i;
1185	struct sd *sd = (struct sd *) gspca_dev;
1186	struct cam *cam = &gspca_dev->cam;
1187
1188	/* frames start with:
1189	 *	ff ff 00 c4 c4 96	synchro
1190	 *	00		(unknown)
1191	 *	xx		(frame sequence / size / compression)
1192	 *	(xx)		(idem - extra byte for sn9c103)
1193	 *	ll mm		brightness sum inside auto exposure
1194	 *	ll mm		brightness sum outside auto exposure
1195	 *	(xx xx xx xx xx)	audio values for snc103
1196	 */
1197	if (len > 6 && len < 24) {
1198		for (i = 0; i < len - 6; i++) {
1199			if (data[0 + i] == 0xff
1200			    && data[1 + i] == 0xff
1201			    && data[2 + i] == 0x00
1202			    && data[3 + i] == 0xc4
1203			    && data[4 + i] == 0xc4
1204			    && data[5 + i] == 0x96) {	/* start of frame */
1205				int lum = -1;
1206				int pkt_type = LAST_PACKET;
1207				int fr_h_sz = (sd->bridge == BRIDGE_103) ?
1208					18 : 12;
1209
1210				if (len - i < fr_h_sz) {
1211					PDEBUG(D_STREAM, "packet too short to"
1212						" get avg brightness");
1213				} else if (sd->bridge == BRIDGE_103) {
1214					lum = data[i + 9] +
1215						(data[i + 10] << 8);
1216				} else {
1217					lum = data[i + 8] + (data[i + 9] << 8);
1218				}
1219				/* When exposure changes midway a frame we
1220				   get a lum of 0 in this case drop 2 frames
1221				   as the frames directly after an exposure
1222				   change have an unstable image. Sometimes lum
1223				   *really* is 0 (cam used in low light with
1224				   low exposure setting), so do not drop frames
1225				   if the previous lum was 0 too. */
1226				if (lum == 0 && sd->prev_avg_lum != 0) {
1227					lum = -1;
1228					sd->frames_to_drop = 2;
1229					sd->prev_avg_lum = 0;
1230				} else
1231					sd->prev_avg_lum = lum;
1232				atomic_set(&sd->avg_lum, lum);
1233
1234				if (sd->frames_to_drop) {
1235					sd->frames_to_drop--;
1236					pkt_type = DISCARD_PACKET;
1237				}
1238
1239				gspca_frame_add(gspca_dev, pkt_type,
1240						NULL, 0);
1241				data += i + fr_h_sz;
1242				len -= i + fr_h_sz;
1243				gspca_frame_add(gspca_dev, FIRST_PACKET,
1244						data, len);
1245				return;
1246			}
1247		}
1248	}
1249
1250	if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
1251		/* In raw mode we sometimes get some garbage after the frame
1252		   ignore this */
1253		int used;
1254		int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
1255
1256		used = gspca_dev->image_len;
1257		if (used + len > size)
1258			len = size - used;
1259	}
1260
1261	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1262}
1263
1264static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1265{
1266	struct sd *sd = (struct sd *) gspca_dev;
1267
1268	sd->brightness = val;
1269	if (gspca_dev->streaming)
1270		setbrightness(gspca_dev);
1271	return 0;
1272}
1273
1274static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1275{
1276	struct sd *sd = (struct sd *) gspca_dev;
1277
1278	*val = sd->brightness;
1279	return 0;
1280}
1281
1282static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1283{
1284	struct sd *sd = (struct sd *) gspca_dev;
1285
1286	sd->gain = val;
1287	if (gspca_dev->streaming)
1288		setgain(gspca_dev);
1289	return 0;
1290}
1291
1292static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1293{
1294	struct sd *sd = (struct sd *) gspca_dev;
1295
1296	*val = sd->gain;
1297	return 0;
1298}
1299
1300static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1301{
1302	struct sd *sd = (struct sd *) gspca_dev;
1303
1304	sd->exposure = val;
1305	if (gspca_dev->streaming)
1306		setexposure(gspca_dev);
1307	return 0;
1308}
1309
1310static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1311{
1312	struct sd *sd = (struct sd *) gspca_dev;
1313
1314	*val = sd->exposure;
1315	return 0;
1316}
1317
1318static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1319{
1320	struct sd *sd = (struct sd *) gspca_dev;
1321
1322	sd->autogain = val;
1323	sd->exp_too_high_cnt = 0;
1324	sd->exp_too_low_cnt = 0;
1325
1326	/* when switching to autogain set defaults to make sure
1327	   we are on a valid point of the autogain gain /
1328	   exposure knee graph, and give this change time to
1329	   take effect before doing autogain. */
1330	if (sd->autogain && !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) {
1331		sd->exposure = EXPOSURE_DEF;
1332		sd->gain = GAIN_DEF;
1333		if (gspca_dev->streaming) {
1334			sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1335			setexposure(gspca_dev);
1336			setgain(gspca_dev);
1337		}
1338	}
1339
1340	return 0;
1341}
1342
1343static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1344{
1345	struct sd *sd = (struct sd *) gspca_dev;
1346
1347	*val = sd->autogain;
1348	return 0;
1349}
1350
1351static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1352{
1353	struct sd *sd = (struct sd *) gspca_dev;
1354
1355	sd->freq = val;
1356	if (gspca_dev->streaming)
1357		setfreq(gspca_dev);
1358	return 0;
1359}
1360
1361static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1362{
1363	struct sd *sd = (struct sd *) gspca_dev;
1364
1365	*val = sd->freq;
1366	return 0;
1367}
1368
1369static int sd_querymenu(struct gspca_dev *gspca_dev,
1370			struct v4l2_querymenu *menu)
1371{
1372	switch (menu->id) {
1373	case V4L2_CID_POWER_LINE_FREQUENCY:
1374		switch (menu->index) {
1375		case 0:		/* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1376			strcpy((char *) menu->name, "NoFliker");
1377			return 0;
1378		case 1:		/* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1379			strcpy((char *) menu->name, "50 Hz");
1380			return 0;
1381		case 2:		/* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1382			strcpy((char *) menu->name, "60 Hz");
1383			return 0;
1384		}
1385		break;
1386	}
1387	return -EINVAL;
1388}
1389
1390#ifdef CONFIG_INPUT
1391static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
1392			u8 *data,		/* interrupt packet data */
1393			int len)		/* interrupt packet length */
1394{
1395	int ret = -EINVAL;
1396
1397	if (len == 1 && data[0] == 1) {
1398		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
1399		input_sync(gspca_dev->input_dev);
1400		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1401		input_sync(gspca_dev->input_dev);
1402		ret = 0;
1403	}
1404
1405	return ret;
1406}
1407#endif
1408
1409/* sub-driver description */
1410static const struct sd_desc sd_desc = {
1411	.name = MODULE_NAME,
1412	.ctrls = sd_ctrls,
1413	.nctrls = ARRAY_SIZE(sd_ctrls),
1414	.config = sd_config,
1415	.init = sd_init,
1416	.start = sd_start,
1417	.stopN = sd_stopN,
1418	.pkt_scan = sd_pkt_scan,
1419	.querymenu = sd_querymenu,
1420	.dq_callback = do_autogain,
1421#ifdef CONFIG_INPUT
1422	.int_pkt_scan = sd_int_pkt_scan,
1423#endif
1424};
1425
1426/* -- module initialisation -- */
1427#define SB(sensor, bridge) \
1428	.driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
1429
1430
1431static const struct usb_device_id device_table[] __devinitconst = {
1432	{USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */
1433	{USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */
1434#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1435	{USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */
1436#endif
1437	{USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
1438	{USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
1439	{USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
1440#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1441	{USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
1442	{USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
1443	{USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
1444#endif
1445	{USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
1446	{USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
1447	{USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1448	{USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
1449	{USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
1450	{USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
1451#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1452	{USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
1453#endif
1454	{USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)},
1455	{}
1456};
1457MODULE_DEVICE_TABLE(usb, device_table);
1458
1459/* -- device connect -- */
1460static int __devinit sd_probe(struct usb_interface *intf,
1461			const struct usb_device_id *id)
1462{
1463	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1464				THIS_MODULE);
1465}
1466
1467static struct usb_driver sd_driver = {
1468	.name = MODULE_NAME,
1469	.id_table = device_table,
1470	.probe = sd_probe,
1471	.disconnect = gspca_disconnect,
1472#ifdef CONFIG_PM
1473	.suspend = gspca_suspend,
1474	.resume = gspca_resume,
1475#endif
1476};
1477
1478/* -- module insert / remove -- */
1479static int __init sd_mod_init(void)
1480{
1481	int ret;
1482	ret = usb_register(&sd_driver);
1483	if (ret < 0)
1484		return ret;
1485	PDEBUG(D_PROBE, "registered");
1486	return 0;
1487}
1488static void __exit sd_mod_exit(void)
1489{
1490	usb_deregister(&sd_driver);
1491	PDEBUG(D_PROBE, "deregistered");
1492}
1493
1494module_init(sd_mod_init);
1495module_exit(sd_mod_exit);
1496