1/*
2 * ov534-ov7xxx gspca driver
3 *
4 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
5 * Copyright (C) 2008 Jim Paris <jim@jtan.com>
6 * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr
7 *
8 * Based on a prototype written by Mark Ferrell <majortrips@gmail.com>
9 * USB protocol reverse engineered by Jim Paris <jim@jtan.com>
10 * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/
11 *
12 * PS3 Eye camera enhanced by Richard Kaswy http://kaswy.free.fr
13 * PS3 Eye camera - brightness, contrast, awb, agc, aec controls
14 *                  added by Max Thrun <bear24rw@gmail.com>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 */
30
31#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
32
33#define MODULE_NAME "ov534"
34
35#include "gspca.h"
36
37#define OV534_REG_ADDRESS	0xf1	/* sensor address */
38#define OV534_REG_SUBADDR	0xf2
39#define OV534_REG_WRITE		0xf3
40#define OV534_REG_READ		0xf4
41#define OV534_REG_OPERATION	0xf5
42#define OV534_REG_STATUS	0xf6
43
44#define OV534_OP_WRITE_3	0x37
45#define OV534_OP_WRITE_2	0x33
46#define OV534_OP_READ_2		0xf9
47
48#define CTRL_TIMEOUT 500
49
50MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
51MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver");
52MODULE_LICENSE("GPL");
53
54/* controls */
55enum e_ctrl {
56	BRIGHTNESS,
57	CONTRAST,
58	GAIN,
59	EXPOSURE,
60	AGC,
61	AWB,
62	AEC,
63	SHARPNESS,
64	HFLIP,
65	VFLIP,
66	COLORS,
67	LIGHTFREQ,
68	NCTRLS		/* number of controls */
69};
70
71/* specific webcam descriptor */
72struct sd {
73	struct gspca_dev gspca_dev;	/* !! must be the first item */
74
75	struct gspca_ctrl ctrls[NCTRLS];
76
77	__u32 last_pts;
78	u16 last_fid;
79	u8 frame_rate;
80
81	u8 sensor;
82};
83enum sensors {
84	SENSOR_OV767x,
85	SENSOR_OV772x,
86	NSENSORS
87};
88
89/* V4L2 controls supported by the driver */
90static void setbrightness(struct gspca_dev *gspca_dev);
91static void setcontrast(struct gspca_dev *gspca_dev);
92static void setgain(struct gspca_dev *gspca_dev);
93static void setexposure(struct gspca_dev *gspca_dev);
94static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val);
95static void setawb(struct gspca_dev *gspca_dev);
96static void setaec(struct gspca_dev *gspca_dev);
97static void setsharpness(struct gspca_dev *gspca_dev);
98static void sethvflip(struct gspca_dev *gspca_dev);
99static void setcolors(struct gspca_dev *gspca_dev);
100static void setlightfreq(struct gspca_dev *gspca_dev);
101
102static int sd_start(struct gspca_dev *gspca_dev);
103static void sd_stopN(struct gspca_dev *gspca_dev);
104
105static const struct ctrl sd_ctrls[] = {
106[BRIGHTNESS] = {
107		{
108			.id      = V4L2_CID_BRIGHTNESS,
109			.type    = V4L2_CTRL_TYPE_INTEGER,
110			.name    = "Brightness",
111			.minimum = 0,
112			.maximum = 255,
113			.step    = 1,
114			.default_value = 0,
115		},
116		.set_control = setbrightness
117	},
118[CONTRAST] = {
119		{
120			.id      = V4L2_CID_CONTRAST,
121			.type    = V4L2_CTRL_TYPE_INTEGER,
122			.name    = "Contrast",
123			.minimum = 0,
124			.maximum = 255,
125			.step    = 1,
126			.default_value = 32,
127		},
128		.set_control = setcontrast
129	},
130[GAIN] = {
131		{
132			.id      = V4L2_CID_GAIN,
133			.type    = V4L2_CTRL_TYPE_INTEGER,
134			.name    = "Main Gain",
135			.minimum = 0,
136			.maximum = 63,
137			.step    = 1,
138			.default_value = 20,
139		},
140		.set_control = setgain
141	},
142[EXPOSURE] = {
143		{
144			.id      = V4L2_CID_EXPOSURE,
145			.type    = V4L2_CTRL_TYPE_INTEGER,
146			.name    = "Exposure",
147			.minimum = 0,
148			.maximum = 255,
149			.step    = 1,
150			.default_value = 120,
151		},
152		.set_control = setexposure
153	},
154[AGC] = {
155		{
156			.id      = V4L2_CID_AUTOGAIN,
157			.type    = V4L2_CTRL_TYPE_BOOLEAN,
158			.name    = "Auto Gain",
159			.minimum = 0,
160			.maximum = 1,
161			.step    = 1,
162			.default_value = 1,
163		},
164		.set = sd_setagc
165	},
166[AWB] = {
167		{
168			.id      = V4L2_CID_AUTO_WHITE_BALANCE,
169			.type    = V4L2_CTRL_TYPE_BOOLEAN,
170			.name    = "Auto White Balance",
171			.minimum = 0,
172			.maximum = 1,
173			.step    = 1,
174			.default_value = 1,
175		},
176		.set_control = setawb
177	},
178[AEC] = {
179		{
180			.id      = V4L2_CID_EXPOSURE_AUTO,
181			.type    = V4L2_CTRL_TYPE_BOOLEAN,
182			.name    = "Auto Exposure",
183			.minimum = 0,
184			.maximum = 1,
185			.step    = 1,
186			.default_value = 1,
187		},
188		.set_control = setaec
189	},
190[SHARPNESS] = {
191		{
192			.id      = V4L2_CID_SHARPNESS,
193			.type    = V4L2_CTRL_TYPE_INTEGER,
194			.name    = "Sharpness",
195			.minimum = 0,
196			.maximum = 63,
197			.step    = 1,
198			.default_value = 0,
199		},
200		.set_control = setsharpness
201	},
202[HFLIP] = {
203		{
204			.id      = V4L2_CID_HFLIP,
205			.type    = V4L2_CTRL_TYPE_BOOLEAN,
206			.name    = "HFlip",
207			.minimum = 0,
208			.maximum = 1,
209			.step    = 1,
210			.default_value = 0,
211		},
212		.set_control = sethvflip
213	},
214[VFLIP] = {
215		{
216			.id      = V4L2_CID_VFLIP,
217			.type    = V4L2_CTRL_TYPE_BOOLEAN,
218			.name    = "VFlip",
219			.minimum = 0,
220			.maximum = 1,
221			.step    = 1,
222			.default_value = 0,
223		},
224		.set_control = sethvflip
225	},
226[COLORS] = {
227		{
228			.id      = V4L2_CID_SATURATION,
229			.type    = V4L2_CTRL_TYPE_INTEGER,
230			.name    = "Saturation",
231			.minimum = 0,
232			.maximum = 6,
233			.step    = 1,
234			.default_value = 3,
235		},
236		.set_control = setcolors
237	},
238[LIGHTFREQ] = {
239		{
240			.id      = V4L2_CID_POWER_LINE_FREQUENCY,
241			.type    = V4L2_CTRL_TYPE_MENU,
242			.name    = "Light Frequency Filter",
243			.minimum = 0,
244			.maximum = 1,
245			.step    = 1,
246			.default_value = 0,
247		},
248		.set_control = setlightfreq
249	},
250};
251
252static const struct v4l2_pix_format ov772x_mode[] = {
253	{320, 240, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
254	 .bytesperline = 320 * 2,
255	 .sizeimage = 320 * 240 * 2,
256	 .colorspace = V4L2_COLORSPACE_SRGB,
257	 .priv = 1},
258	{640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE,
259	 .bytesperline = 640 * 2,
260	 .sizeimage = 640 * 480 * 2,
261	 .colorspace = V4L2_COLORSPACE_SRGB,
262	 .priv = 0},
263};
264static const struct v4l2_pix_format ov767x_mode[] = {
265	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
266		.bytesperline = 320,
267		.sizeimage = 320 * 240 * 3 / 8 + 590,
268		.colorspace = V4L2_COLORSPACE_JPEG},
269	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
270		.bytesperline = 640,
271		.sizeimage = 640 * 480 * 3 / 8 + 590,
272		.colorspace = V4L2_COLORSPACE_JPEG},
273};
274
275static const u8 qvga_rates[] = {125, 100, 75, 60, 50, 40, 30};
276static const u8 vga_rates[] = {60, 50, 40, 30, 15};
277
278static const struct framerates ov772x_framerates[] = {
279	{ /* 320x240 */
280		.rates = qvga_rates,
281		.nrates = ARRAY_SIZE(qvga_rates),
282	},
283	{ /* 640x480 */
284		.rates = vga_rates,
285		.nrates = ARRAY_SIZE(vga_rates),
286	},
287};
288
289struct reg_array {
290	const u8 (*val)[2];
291	int len;
292};
293
294static const u8 bridge_init_767x[][2] = {
295/* comments from the ms-win file apollo7670.set */
296/* str1 */
297	{0xf1, 0x42},
298	{0x88, 0xf8},
299	{0x89, 0xff},
300	{0x76, 0x03},
301	{0x92, 0x03},
302	{0x95, 0x10},
303	{0xe2, 0x00},
304	{0xe7, 0x3e},
305	{0x8d, 0x1c},
306	{0x8e, 0x00},
307	{0x8f, 0x00},
308	{0x1f, 0x00},
309	{0xc3, 0xf9},
310	{0x89, 0xff},
311	{0x88, 0xf8},
312	{0x76, 0x03},
313	{0x92, 0x01},
314	{0x93, 0x18},
315	{0x1c, 0x00},
316	{0x1d, 0x48},
317	{0x1d, 0x00},
318	{0x1d, 0xff},
319	{0x1d, 0x02},
320	{0x1d, 0x58},
321	{0x1d, 0x00},
322	{0x1c, 0x0a},
323	{0x1d, 0x0a},
324	{0x1d, 0x0e},
325	{0xc0, 0x50},	/* HSize 640 */
326	{0xc1, 0x3c},	/* VSize 480 */
327	{0x34, 0x05},	/* enable Audio Suspend mode */
328	{0xc2, 0x0c},	/* Input YUV */
329	{0xc3, 0xf9},	/* enable PRE */
330	{0x34, 0x05},	/* enable Audio Suspend mode */
331	{0xe7, 0x2e},	/* this solves failure of "SuspendResumeTest" */
332	{0x31, 0xf9},	/* enable 1.8V Suspend */
333	{0x35, 0x02},	/* turn on JPEG */
334	{0xd9, 0x10},
335	{0x25, 0x42},	/* GPIO[8]:Input */
336	{0x94, 0x11},	/* If the default setting is loaded when
337			 * system boots up, this flag is closed here */
338};
339static const u8 sensor_init_767x[][2] = {
340	{0x12, 0x80},
341	{0x11, 0x03},
342	{0x3a, 0x04},
343	{0x12, 0x00},
344	{0x17, 0x13},
345	{0x18, 0x01},
346	{0x32, 0xb6},
347	{0x19, 0x02},
348	{0x1a, 0x7a},
349	{0x03, 0x0a},
350	{0x0c, 0x00},
351	{0x3e, 0x00},
352	{0x70, 0x3a},
353	{0x71, 0x35},
354	{0x72, 0x11},
355	{0x73, 0xf0},
356	{0xa2, 0x02},
357	{0x7a, 0x2a},	/* set Gamma=1.6 below */
358	{0x7b, 0x12},
359	{0x7c, 0x1d},
360	{0x7d, 0x2d},
361	{0x7e, 0x45},
362	{0x7f, 0x50},
363	{0x80, 0x59},
364	{0x81, 0x62},
365	{0x82, 0x6b},
366	{0x83, 0x73},
367	{0x84, 0x7b},
368	{0x85, 0x8a},
369	{0x86, 0x98},
370	{0x87, 0xb2},
371	{0x88, 0xca},
372	{0x89, 0xe0},
373	{0x13, 0xe0},
374	{0x00, 0x00},
375	{0x10, 0x00},
376	{0x0d, 0x40},
377	{0x14, 0x38},	/* gain max 16x */
378	{0xa5, 0x05},
379	{0xab, 0x07},
380	{0x24, 0x95},
381	{0x25, 0x33},
382	{0x26, 0xe3},
383	{0x9f, 0x78},
384	{0xa0, 0x68},
385	{0xa1, 0x03},
386	{0xa6, 0xd8},
387	{0xa7, 0xd8},
388	{0xa8, 0xf0},
389	{0xa9, 0x90},
390	{0xaa, 0x94},
391	{0x13, 0xe5},
392	{0x0e, 0x61},
393	{0x0f, 0x4b},
394	{0x16, 0x02},
395	{0x21, 0x02},
396	{0x22, 0x91},
397	{0x29, 0x07},
398	{0x33, 0x0b},
399	{0x35, 0x0b},
400	{0x37, 0x1d},
401	{0x38, 0x71},
402	{0x39, 0x2a},
403	{0x3c, 0x78},
404	{0x4d, 0x40},
405	{0x4e, 0x20},
406	{0x69, 0x00},
407	{0x6b, 0x4a},
408	{0x74, 0x10},
409	{0x8d, 0x4f},
410	{0x8e, 0x00},
411	{0x8f, 0x00},
412	{0x90, 0x00},
413	{0x91, 0x00},
414	{0x96, 0x00},
415	{0x9a, 0x80},
416	{0xb0, 0x84},
417	{0xb1, 0x0c},
418	{0xb2, 0x0e},
419	{0xb3, 0x82},
420	{0xb8, 0x0a},
421	{0x43, 0x0a},
422	{0x44, 0xf0},
423	{0x45, 0x34},
424	{0x46, 0x58},
425	{0x47, 0x28},
426	{0x48, 0x3a},
427	{0x59, 0x88},
428	{0x5a, 0x88},
429	{0x5b, 0x44},
430	{0x5c, 0x67},
431	{0x5d, 0x49},
432	{0x5e, 0x0e},
433	{0x6c, 0x0a},
434	{0x6d, 0x55},
435	{0x6e, 0x11},
436	{0x6f, 0x9f},
437	{0x6a, 0x40},
438	{0x01, 0x40},
439	{0x02, 0x40},
440	{0x13, 0xe7},
441	{0x4f, 0x80},
442	{0x50, 0x80},
443	{0x51, 0x00},
444	{0x52, 0x22},
445	{0x53, 0x5e},
446	{0x54, 0x80},
447	{0x58, 0x9e},
448	{0x41, 0x08},
449	{0x3f, 0x00},
450	{0x75, 0x04},
451	{0x76, 0xe1},
452	{0x4c, 0x00},
453	{0x77, 0x01},
454	{0x3d, 0xc2},
455	{0x4b, 0x09},
456	{0xc9, 0x60},
457	{0x41, 0x38},	/* jfm: auto sharpness + auto de-noise  */
458	{0x56, 0x40},
459	{0x34, 0x11},
460	{0x3b, 0xc2},
461	{0xa4, 0x8a},	/* Night mode trigger point */
462	{0x96, 0x00},
463	{0x97, 0x30},
464	{0x98, 0x20},
465	{0x99, 0x20},
466	{0x9a, 0x84},
467	{0x9b, 0x29},
468	{0x9c, 0x03},
469	{0x9d, 0x4c},
470	{0x9e, 0x3f},
471	{0x78, 0x04},
472	{0x79, 0x01},
473	{0xc8, 0xf0},
474	{0x79, 0x0f},
475	{0xc8, 0x00},
476	{0x79, 0x10},
477	{0xc8, 0x7e},
478	{0x79, 0x0a},
479	{0xc8, 0x80},
480	{0x79, 0x0b},
481	{0xc8, 0x01},
482	{0x79, 0x0c},
483	{0xc8, 0x0f},
484	{0x79, 0x0d},
485	{0xc8, 0x20},
486	{0x79, 0x09},
487	{0xc8, 0x80},
488	{0x79, 0x02},
489	{0xc8, 0xc0},
490	{0x79, 0x03},
491	{0xc8, 0x20},
492	{0x79, 0x26},
493};
494static const u8 bridge_start_vga_767x[][2] = {
495/* str59 JPG */
496	{0x94, 0xaa},
497	{0xf1, 0x42},
498	{0xe5, 0x04},
499	{0xc0, 0x50},
500	{0xc1, 0x3c},
501	{0xc2, 0x0c},
502	{0x35, 0x02},	/* turn on JPEG */
503	{0xd9, 0x10},
504	{0xda, 0x00},	/* for higher clock rate(30fps) */
505	{0x34, 0x05},	/* enable Audio Suspend mode */
506	{0xc3, 0xf9},	/* enable PRE */
507	{0x8c, 0x00},	/* CIF VSize LSB[2:0] */
508	{0x8d, 0x1c},	/* output YUV */
509/*	{0x34, 0x05},	 * enable Audio Suspend mode (?) */
510	{0x50, 0x00},	/* H/V divider=0 */
511	{0x51, 0xa0},	/* input H=640/4 */
512	{0x52, 0x3c},	/* input V=480/4 */
513	{0x53, 0x00},	/* offset X=0 */
514	{0x54, 0x00},	/* offset Y=0 */
515	{0x55, 0x00},	/* H/V size[8]=0 */
516	{0x57, 0x00},	/* H-size[9]=0 */
517	{0x5c, 0x00},	/* output size[9:8]=0 */
518	{0x5a, 0xa0},	/* output H=640/4 */
519	{0x5b, 0x78},	/* output V=480/4 */
520	{0x1c, 0x0a},
521	{0x1d, 0x0a},
522	{0x94, 0x11},
523};
524static const u8 sensor_start_vga_767x[][2] = {
525	{0x11, 0x01},
526	{0x1e, 0x04},
527	{0x19, 0x02},
528	{0x1a, 0x7a},
529};
530static const u8 bridge_start_qvga_767x[][2] = {
531/* str86 JPG */
532	{0x94, 0xaa},
533	{0xf1, 0x42},
534	{0xe5, 0x04},
535	{0xc0, 0x80},
536	{0xc1, 0x60},
537	{0xc2, 0x0c},
538	{0x35, 0x02},	/* turn on JPEG */
539	{0xd9, 0x10},
540	{0xc0, 0x50},	/* CIF HSize 640 */
541	{0xc1, 0x3c},	/* CIF VSize 480 */
542	{0x8c, 0x00},	/* CIF VSize LSB[2:0] */
543	{0x8d, 0x1c},	/* output YUV */
544	{0x34, 0x05},	/* enable Audio Suspend mode */
545	{0xc2, 0x4c},	/* output YUV and Enable DCW */
546	{0xc3, 0xf9},	/* enable PRE */
547	{0x1c, 0x00},	/* indirect addressing */
548	{0x1d, 0x48},	/* output YUV422 */
549	{0x50, 0x89},	/* H/V divider=/2; plus DCW AVG */
550	{0x51, 0xa0},	/* DCW input H=640/4 */
551	{0x52, 0x78},	/* DCW input V=480/4 */
552	{0x53, 0x00},	/* offset X=0 */
553	{0x54, 0x00},	/* offset Y=0 */
554	{0x55, 0x00},	/* H/V size[8]=0 */
555	{0x57, 0x00},	/* H-size[9]=0 */
556	{0x5c, 0x00},	/* DCW output size[9:8]=0 */
557	{0x5a, 0x50},	/* DCW output H=320/4 */
558	{0x5b, 0x3c},	/* DCW output V=240/4 */
559	{0x1c, 0x0a},
560	{0x1d, 0x0a},
561	{0x94, 0x11},
562};
563static const u8 sensor_start_qvga_767x[][2] = {
564	{0x11, 0x01},
565	{0x1e, 0x04},
566	{0x19, 0x02},
567	{0x1a, 0x7a},
568};
569
570static const u8 bridge_init_772x[][2] = {
571	{ 0xc2, 0x0c },
572	{ 0x88, 0xf8 },
573	{ 0xc3, 0x69 },
574	{ 0x89, 0xff },
575	{ 0x76, 0x03 },
576	{ 0x92, 0x01 },
577	{ 0x93, 0x18 },
578	{ 0x94, 0x10 },
579	{ 0x95, 0x10 },
580	{ 0xe2, 0x00 },
581	{ 0xe7, 0x3e },
582
583	{ 0x96, 0x00 },
584
585	{ 0x97, 0x20 },
586	{ 0x97, 0x20 },
587	{ 0x97, 0x20 },
588	{ 0x97, 0x0a },
589	{ 0x97, 0x3f },
590	{ 0x97, 0x4a },
591	{ 0x97, 0x20 },
592	{ 0x97, 0x15 },
593	{ 0x97, 0x0b },
594
595	{ 0x8e, 0x40 },
596	{ 0x1f, 0x81 },
597	{ 0x34, 0x05 },
598	{ 0xe3, 0x04 },
599	{ 0x88, 0x00 },
600	{ 0x89, 0x00 },
601	{ 0x76, 0x00 },
602	{ 0xe7, 0x2e },
603	{ 0x31, 0xf9 },
604	{ 0x25, 0x42 },
605	{ 0x21, 0xf0 },
606
607	{ 0x1c, 0x00 },
608	{ 0x1d, 0x40 },
609	{ 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */
610	{ 0x1d, 0x00 }, /* payload size */
611
612	{ 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */
613	{ 0x1d, 0x58 }, /* frame size */
614	{ 0x1d, 0x00 }, /* frame size */
615
616	{ 0x1c, 0x0a },
617	{ 0x1d, 0x08 }, /* turn on UVC header */
618	{ 0x1d, 0x0e }, /* .. */
619
620	{ 0x8d, 0x1c },
621	{ 0x8e, 0x80 },
622	{ 0xe5, 0x04 },
623
624	{ 0xc0, 0x50 },
625	{ 0xc1, 0x3c },
626	{ 0xc2, 0x0c },
627};
628static const u8 sensor_init_772x[][2] = {
629	{ 0x12, 0x80 },
630	{ 0x11, 0x01 },
631/*fixme: better have a delay?*/
632	{ 0x11, 0x01 },
633	{ 0x11, 0x01 },
634	{ 0x11, 0x01 },
635	{ 0x11, 0x01 },
636	{ 0x11, 0x01 },
637	{ 0x11, 0x01 },
638	{ 0x11, 0x01 },
639	{ 0x11, 0x01 },
640	{ 0x11, 0x01 },
641	{ 0x11, 0x01 },
642
643	{ 0x3d, 0x03 },
644	{ 0x17, 0x26 },
645	{ 0x18, 0xa0 },
646	{ 0x19, 0x07 },
647	{ 0x1a, 0xf0 },
648	{ 0x32, 0x00 },
649	{ 0x29, 0xa0 },
650	{ 0x2c, 0xf0 },
651	{ 0x65, 0x20 },
652	{ 0x11, 0x01 },
653	{ 0x42, 0x7f },
654	{ 0x63, 0xaa },		/* AWB - was e0 */
655	{ 0x64, 0xff },
656	{ 0x66, 0x00 },
657	{ 0x13, 0xf0 },		/* com8 */
658	{ 0x0d, 0x41 },
659	{ 0x0f, 0xc5 },
660	{ 0x14, 0x11 },
661
662	{ 0x22, 0x7f },
663	{ 0x23, 0x03 },
664	{ 0x24, 0x40 },
665	{ 0x25, 0x30 },
666	{ 0x26, 0xa1 },
667	{ 0x2a, 0x00 },
668	{ 0x2b, 0x00 },
669	{ 0x6b, 0xaa },
670	{ 0x13, 0xff },		/* AWB */
671
672	{ 0x90, 0x05 },
673	{ 0x91, 0x01 },
674	{ 0x92, 0x03 },
675	{ 0x93, 0x00 },
676	{ 0x94, 0x60 },
677	{ 0x95, 0x3c },
678	{ 0x96, 0x24 },
679	{ 0x97, 0x1e },
680	{ 0x98, 0x62 },
681	{ 0x99, 0x80 },
682	{ 0x9a, 0x1e },
683	{ 0x9b, 0x08 },
684	{ 0x9c, 0x20 },
685	{ 0x9e, 0x81 },
686
687	{ 0xa6, 0x04 },
688	{ 0x7e, 0x0c },
689	{ 0x7f, 0x16 },
690	{ 0x80, 0x2a },
691	{ 0x81, 0x4e },
692	{ 0x82, 0x61 },
693	{ 0x83, 0x6f },
694	{ 0x84, 0x7b },
695	{ 0x85, 0x86 },
696	{ 0x86, 0x8e },
697	{ 0x87, 0x97 },
698	{ 0x88, 0xa4 },
699	{ 0x89, 0xaf },
700	{ 0x8a, 0xc5 },
701	{ 0x8b, 0xd7 },
702	{ 0x8c, 0xe8 },
703	{ 0x8d, 0x20 },
704
705	{ 0x0c, 0x90 },
706
707	{ 0x2b, 0x00 },
708	{ 0x22, 0x7f },
709	{ 0x23, 0x03 },
710	{ 0x11, 0x01 },
711	{ 0x0c, 0xd0 },
712	{ 0x64, 0xff },
713	{ 0x0d, 0x41 },
714
715	{ 0x14, 0x41 },
716	{ 0x0e, 0xcd },
717	{ 0xac, 0xbf },
718	{ 0x8e, 0x00 },		/* De-noise threshold */
719	{ 0x0c, 0xd0 }
720};
721static const u8 bridge_start_vga_772x[][2] = {
722	{0x1c, 0x00},
723	{0x1d, 0x40},
724	{0x1d, 0x02},
725	{0x1d, 0x00},
726	{0x1d, 0x02},
727	{0x1d, 0x58},
728	{0x1d, 0x00},
729	{0xc0, 0x50},
730	{0xc1, 0x3c},
731};
732static const u8 sensor_start_vga_772x[][2] = {
733	{0x12, 0x00},
734	{0x17, 0x26},
735	{0x18, 0xa0},
736	{0x19, 0x07},
737	{0x1a, 0xf0},
738	{0x29, 0xa0},
739	{0x2c, 0xf0},
740	{0x65, 0x20},
741};
742static const u8 bridge_start_qvga_772x[][2] = {
743	{0x1c, 0x00},
744	{0x1d, 0x40},
745	{0x1d, 0x02},
746	{0x1d, 0x00},
747	{0x1d, 0x01},
748	{0x1d, 0x4b},
749	{0x1d, 0x00},
750	{0xc0, 0x28},
751	{0xc1, 0x1e},
752};
753static const u8 sensor_start_qvga_772x[][2] = {
754	{0x12, 0x40},
755	{0x17, 0x3f},
756	{0x18, 0x50},
757	{0x19, 0x03},
758	{0x1a, 0x78},
759	{0x29, 0x50},
760	{0x2c, 0x78},
761	{0x65, 0x2f},
762};
763
764static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
765{
766	struct usb_device *udev = gspca_dev->dev;
767	int ret;
768
769	if (gspca_dev->usb_err < 0)
770		return;
771
772	PDEBUG(D_USBO, "SET 01 0000 %04x %02x", reg, val);
773	gspca_dev->usb_buf[0] = val;
774	ret = usb_control_msg(udev,
775			      usb_sndctrlpipe(udev, 0),
776			      0x01,
777			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
778			      0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
779	if (ret < 0) {
780		pr_err("write failed %d\n", ret);
781		gspca_dev->usb_err = ret;
782	}
783}
784
785static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
786{
787	struct usb_device *udev = gspca_dev->dev;
788	int ret;
789
790	if (gspca_dev->usb_err < 0)
791		return 0;
792	ret = usb_control_msg(udev,
793			      usb_rcvctrlpipe(udev, 0),
794			      0x01,
795			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
796			      0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
797	PDEBUG(D_USBI, "GET 01 0000 %04x %02x", reg, gspca_dev->usb_buf[0]);
798	if (ret < 0) {
799		pr_err("read failed %d\n", ret);
800		gspca_dev->usb_err = ret;
801	}
802	return gspca_dev->usb_buf[0];
803}
804
805/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
806 * (direction and output)? */
807static void ov534_set_led(struct gspca_dev *gspca_dev, int status)
808{
809	u8 data;
810
811	PDEBUG(D_CONF, "led status: %d", status);
812
813	data = ov534_reg_read(gspca_dev, 0x21);
814	data |= 0x80;
815	ov534_reg_write(gspca_dev, 0x21, data);
816
817	data = ov534_reg_read(gspca_dev, 0x23);
818	if (status)
819		data |= 0x80;
820	else
821		data &= ~0x80;
822
823	ov534_reg_write(gspca_dev, 0x23, data);
824
825	if (!status) {
826		data = ov534_reg_read(gspca_dev, 0x21);
827		data &= ~0x80;
828		ov534_reg_write(gspca_dev, 0x21, data);
829	}
830}
831
832static int sccb_check_status(struct gspca_dev *gspca_dev)
833{
834	u8 data;
835	int i;
836
837	for (i = 0; i < 5; i++) {
838		data = ov534_reg_read(gspca_dev, OV534_REG_STATUS);
839
840		switch (data) {
841		case 0x00:
842			return 1;
843		case 0x04:
844			return 0;
845		case 0x03:
846			break;
847		default:
848			PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5",
849			       data, i + 1);
850		}
851	}
852	return 0;
853}
854
855static void sccb_reg_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
856{
857	PDEBUG(D_USBO, "sccb write: %02x %02x", reg, val);
858	ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
859	ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
860	ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
861
862	if (!sccb_check_status(gspca_dev)) {
863		pr_err("sccb_reg_write failed\n");
864		gspca_dev->usb_err = -EIO;
865	}
866}
867
868static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg)
869{
870	ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
871	ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
872	if (!sccb_check_status(gspca_dev))
873		pr_err("sccb_reg_read failed 1\n");
874
875	ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
876	if (!sccb_check_status(gspca_dev))
877		pr_err("sccb_reg_read failed 2\n");
878
879	return ov534_reg_read(gspca_dev, OV534_REG_READ);
880}
881
882/* output a bridge sequence (reg - val) */
883static void reg_w_array(struct gspca_dev *gspca_dev,
884			const u8 (*data)[2], int len)
885{
886	while (--len >= 0) {
887		ov534_reg_write(gspca_dev, (*data)[0], (*data)[1]);
888		data++;
889	}
890}
891
892/* output a sensor sequence (reg - val) */
893static void sccb_w_array(struct gspca_dev *gspca_dev,
894			const u8 (*data)[2], int len)
895{
896	while (--len >= 0) {
897		if ((*data)[0] != 0xff) {
898			sccb_reg_write(gspca_dev, (*data)[0], (*data)[1]);
899		} else {
900			sccb_reg_read(gspca_dev, (*data)[1]);
901			sccb_reg_write(gspca_dev, 0xff, 0x00);
902		}
903		data++;
904	}
905}
906
907/* ov772x specific controls */
908static void set_frame_rate(struct gspca_dev *gspca_dev)
909{
910	struct sd *sd = (struct sd *) gspca_dev;
911	int i;
912	struct rate_s {
913		u8 fps;
914		u8 r11;
915		u8 r0d;
916		u8 re5;
917	};
918	const struct rate_s *r;
919	static const struct rate_s rate_0[] = {	/* 640x480 */
920		{60, 0x01, 0xc1, 0x04},
921		{50, 0x01, 0x41, 0x02},
922		{40, 0x02, 0xc1, 0x04},
923		{30, 0x04, 0x81, 0x02},
924		{15, 0x03, 0x41, 0x04},
925	};
926	static const struct rate_s rate_1[] = {	/* 320x240 */
927		{125, 0x02, 0x81, 0x02},
928		{100, 0x02, 0xc1, 0x04},
929		{75, 0x03, 0xc1, 0x04},
930		{60, 0x04, 0xc1, 0x04},
931		{50, 0x02, 0x41, 0x04},
932		{40, 0x03, 0x41, 0x04},
933		{30, 0x04, 0x41, 0x04},
934	};
935
936	if (sd->sensor != SENSOR_OV772x)
937		return;
938	if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv == 0) {
939		r = rate_0;
940		i = ARRAY_SIZE(rate_0);
941	} else {
942		r = rate_1;
943		i = ARRAY_SIZE(rate_1);
944	}
945	while (--i > 0) {
946		if (sd->frame_rate >= r->fps)
947			break;
948		r++;
949	}
950
951	sccb_reg_write(gspca_dev, 0x11, r->r11);
952	sccb_reg_write(gspca_dev, 0x0d, r->r0d);
953	ov534_reg_write(gspca_dev, 0xe5, r->re5);
954
955	PDEBUG(D_PROBE, "frame_rate: %d", r->fps);
956}
957
958static void setbrightness(struct gspca_dev *gspca_dev)
959{
960	struct sd *sd = (struct sd *) gspca_dev;
961	int val;
962
963	val = sd->ctrls[BRIGHTNESS].val;
964	if (sd->sensor == SENSOR_OV767x) {
965		if (val < 0)
966			val = 0x80 - val;
967		sccb_reg_write(gspca_dev, 0x55, val);	/* bright */
968	} else {
969		sccb_reg_write(gspca_dev, 0x9b, val);
970	}
971}
972
973static void setcontrast(struct gspca_dev *gspca_dev)
974{
975	struct sd *sd = (struct sd *) gspca_dev;
976	u8 val;
977
978	val = sd->ctrls[CONTRAST].val;
979	if (sd->sensor == SENSOR_OV767x)
980		sccb_reg_write(gspca_dev, 0x56, val);	/* contras */
981	else
982		sccb_reg_write(gspca_dev, 0x9c, val);
983}
984
985static void setgain(struct gspca_dev *gspca_dev)
986{
987	struct sd *sd = (struct sd *) gspca_dev;
988	u8 val;
989
990	if (sd->ctrls[AGC].val)
991		return;
992
993	val = sd->ctrls[GAIN].val;
994	switch (val & 0x30) {
995	case 0x00:
996		val &= 0x0f;
997		break;
998	case 0x10:
999		val &= 0x0f;
1000		val |= 0x30;
1001		break;
1002	case 0x20:
1003		val &= 0x0f;
1004		val |= 0x70;
1005		break;
1006	default:
1007/*	case 0x30: */
1008		val &= 0x0f;
1009		val |= 0xf0;
1010		break;
1011	}
1012	sccb_reg_write(gspca_dev, 0x00, val);
1013}
1014
1015static void setexposure(struct gspca_dev *gspca_dev)
1016{
1017	struct sd *sd = (struct sd *) gspca_dev;
1018	u8 val;
1019
1020	if (sd->ctrls[AEC].val)
1021		return;
1022
1023	val = sd->ctrls[EXPOSURE].val;
1024	if (sd->sensor == SENSOR_OV767x) {
1025
1026		/* set only aec[9:2] */
1027		sccb_reg_write(gspca_dev, 0x10, val);	/* aech */
1028	} else {
1029
1030		/* 'val' is one byte and represents half of the exposure value
1031		 * we are going to set into registers, a two bytes value:
1032		 *
1033		 *    MSB: ((u16) val << 1) >> 8   == val >> 7
1034		 *    LSB: ((u16) val << 1) & 0xff == val << 1
1035		 */
1036		sccb_reg_write(gspca_dev, 0x08, val >> 7);
1037		sccb_reg_write(gspca_dev, 0x10, val << 1);
1038	}
1039}
1040
1041static void setagc(struct gspca_dev *gspca_dev)
1042{
1043	struct sd *sd = (struct sd *) gspca_dev;
1044
1045	if (sd->ctrls[AGC].val) {
1046		sccb_reg_write(gspca_dev, 0x13,
1047				sccb_reg_read(gspca_dev, 0x13) | 0x04);
1048		sccb_reg_write(gspca_dev, 0x64,
1049				sccb_reg_read(gspca_dev, 0x64) | 0x03);
1050	} else {
1051		sccb_reg_write(gspca_dev, 0x13,
1052				sccb_reg_read(gspca_dev, 0x13) & ~0x04);
1053		sccb_reg_write(gspca_dev, 0x64,
1054				sccb_reg_read(gspca_dev, 0x64) & ~0x03);
1055
1056		setgain(gspca_dev);
1057	}
1058}
1059
1060static void setawb(struct gspca_dev *gspca_dev)
1061{
1062	struct sd *sd = (struct sd *) gspca_dev;
1063
1064	if (sd->ctrls[AWB].val) {
1065		sccb_reg_write(gspca_dev, 0x13,
1066				sccb_reg_read(gspca_dev, 0x13) | 0x02);
1067		if (sd->sensor == SENSOR_OV772x)
1068			sccb_reg_write(gspca_dev, 0x63,
1069				sccb_reg_read(gspca_dev, 0x63) | 0xc0);
1070	} else {
1071		sccb_reg_write(gspca_dev, 0x13,
1072				sccb_reg_read(gspca_dev, 0x13) & ~0x02);
1073		if (sd->sensor == SENSOR_OV772x)
1074			sccb_reg_write(gspca_dev, 0x63,
1075				sccb_reg_read(gspca_dev, 0x63) & ~0xc0);
1076	}
1077}
1078
1079static void setaec(struct gspca_dev *gspca_dev)
1080{
1081	struct sd *sd = (struct sd *) gspca_dev;
1082	u8 data;
1083
1084	data = sd->sensor == SENSOR_OV767x ?
1085			0x05 :		/* agc + aec */
1086			0x01;		/* agc */
1087	if (sd->ctrls[AEC].val)
1088		sccb_reg_write(gspca_dev, 0x13,
1089				sccb_reg_read(gspca_dev, 0x13) | data);
1090	else {
1091		sccb_reg_write(gspca_dev, 0x13,
1092				sccb_reg_read(gspca_dev, 0x13) & ~data);
1093		if (sd->sensor == SENSOR_OV767x)
1094			sd->ctrls[EXPOSURE].val =
1095				sccb_reg_read(gspca_dev, 10);	/* aech */
1096		else
1097			setexposure(gspca_dev);
1098	}
1099}
1100
1101static void setsharpness(struct gspca_dev *gspca_dev)
1102{
1103	struct sd *sd = (struct sd *) gspca_dev;
1104	u8 val;
1105
1106	val = sd->ctrls[SHARPNESS].val;
1107	sccb_reg_write(gspca_dev, 0x91, val);	/* Auto de-noise threshold */
1108	sccb_reg_write(gspca_dev, 0x8e, val);	/* De-noise threshold */
1109}
1110
1111static void sethvflip(struct gspca_dev *gspca_dev)
1112{
1113	struct sd *sd = (struct sd *) gspca_dev;
1114	u8 val;
1115
1116	if (sd->sensor == SENSOR_OV767x) {
1117		val = sccb_reg_read(gspca_dev, 0x1e);	/* mvfp */
1118		val &= ~0x30;
1119		if (sd->ctrls[HFLIP].val)
1120			val |= 0x20;
1121		if (sd->ctrls[VFLIP].val)
1122			val |= 0x10;
1123		sccb_reg_write(gspca_dev, 0x1e, val);
1124	} else {
1125		val = sccb_reg_read(gspca_dev, 0x0c);
1126		val &= ~0xc0;
1127		if (sd->ctrls[HFLIP].val == 0)
1128			val |= 0x40;
1129		if (sd->ctrls[VFLIP].val == 0)
1130			val |= 0x80;
1131		sccb_reg_write(gspca_dev, 0x0c, val);
1132	}
1133}
1134
1135static void setcolors(struct gspca_dev *gspca_dev)
1136{
1137	struct sd *sd = (struct sd *) gspca_dev;
1138	u8 val;
1139	int i;
1140	static u8 color_tb[][6] = {
1141		{0x42, 0x42, 0x00, 0x11, 0x30, 0x41},
1142		{0x52, 0x52, 0x00, 0x16, 0x3c, 0x52},
1143		{0x66, 0x66, 0x00, 0x1b, 0x4b, 0x66},
1144		{0x80, 0x80, 0x00, 0x22, 0x5e, 0x80},
1145		{0x9a, 0x9a, 0x00, 0x29, 0x71, 0x9a},
1146		{0xb8, 0xb8, 0x00, 0x31, 0x87, 0xb8},
1147		{0xdd, 0xdd, 0x00, 0x3b, 0xa2, 0xdd},
1148	};
1149
1150	val = sd->ctrls[COLORS].val;
1151	for (i = 0; i < ARRAY_SIZE(color_tb[0]); i++)
1152		sccb_reg_write(gspca_dev, 0x4f + i, color_tb[val][i]);
1153}
1154
1155static void setlightfreq(struct gspca_dev *gspca_dev)
1156{
1157	struct sd *sd = (struct sd *) gspca_dev;
1158	u8 val;
1159
1160	val = sd->ctrls[LIGHTFREQ].val ? 0x9e : 0x00;
1161	if (sd->sensor == SENSOR_OV767x) {
1162		sccb_reg_write(gspca_dev, 0x2a, 0x00);
1163		if (val)
1164			val = 0x9d;	/* insert dummy to 25fps for 50Hz */
1165	}
1166	sccb_reg_write(gspca_dev, 0x2b, val);
1167}
1168
1169
1170/* this function is called at probe time */
1171static int sd_config(struct gspca_dev *gspca_dev,
1172		     const struct usb_device_id *id)
1173{
1174	struct sd *sd = (struct sd *) gspca_dev;
1175	struct cam *cam;
1176
1177	cam = &gspca_dev->cam;
1178
1179	cam->ctrls = sd->ctrls;
1180
1181	/* the auto white balance control works only when auto gain is set */
1182	if (sd_ctrls[AGC].qctrl.default_value == 0)
1183		gspca_dev->ctrl_inac |= (1 << AWB);
1184
1185	cam->cam_mode = ov772x_mode;
1186	cam->nmodes = ARRAY_SIZE(ov772x_mode);
1187
1188	sd->frame_rate = 30;
1189
1190	return 0;
1191}
1192
1193/* this function is called at probe and resume time */
1194static int sd_init(struct gspca_dev *gspca_dev)
1195{
1196	struct sd *sd = (struct sd *) gspca_dev;
1197	u16 sensor_id;
1198	static const struct reg_array bridge_init[NSENSORS] = {
1199	[SENSOR_OV767x] = {bridge_init_767x, ARRAY_SIZE(bridge_init_767x)},
1200	[SENSOR_OV772x] = {bridge_init_772x, ARRAY_SIZE(bridge_init_772x)},
1201	};
1202	static const struct reg_array sensor_init[NSENSORS] = {
1203	[SENSOR_OV767x] = {sensor_init_767x, ARRAY_SIZE(sensor_init_767x)},
1204	[SENSOR_OV772x] = {sensor_init_772x, ARRAY_SIZE(sensor_init_772x)},
1205	};
1206
1207	/* reset bridge */
1208	ov534_reg_write(gspca_dev, 0xe7, 0x3a);
1209	ov534_reg_write(gspca_dev, 0xe0, 0x08);
1210	msleep(100);
1211
1212	/* initialize the sensor address */
1213	ov534_reg_write(gspca_dev, OV534_REG_ADDRESS, 0x42);
1214
1215	/* reset sensor */
1216	sccb_reg_write(gspca_dev, 0x12, 0x80);
1217	msleep(10);
1218
1219	/* probe the sensor */
1220	sccb_reg_read(gspca_dev, 0x0a);
1221	sensor_id = sccb_reg_read(gspca_dev, 0x0a) << 8;
1222	sccb_reg_read(gspca_dev, 0x0b);
1223	sensor_id |= sccb_reg_read(gspca_dev, 0x0b);
1224	PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
1225
1226	if ((sensor_id & 0xfff0) == 0x7670) {
1227		sd->sensor = SENSOR_OV767x;
1228		gspca_dev->ctrl_dis = (1 << GAIN) |
1229					(1 << AGC) |
1230					(1 << SHARPNESS);	/* auto */
1231		sd->ctrls[BRIGHTNESS].min = -127;
1232		sd->ctrls[BRIGHTNESS].max = 127;
1233		sd->ctrls[BRIGHTNESS].def = 0;
1234		sd->ctrls[CONTRAST].max = 0x80;
1235		sd->ctrls[CONTRAST].def = 0x40;
1236		sd->ctrls[EXPOSURE].min = 0x08;
1237		sd->ctrls[EXPOSURE].max = 0x60;
1238		sd->ctrls[EXPOSURE].def = 0x13;
1239		sd->ctrls[SHARPNESS].max = 9;
1240		sd->ctrls[SHARPNESS].def = 4;
1241		sd->ctrls[HFLIP].def = 1;
1242		gspca_dev->cam.cam_mode = ov767x_mode;
1243		gspca_dev->cam.nmodes = ARRAY_SIZE(ov767x_mode);
1244	} else {
1245		sd->sensor = SENSOR_OV772x;
1246		gspca_dev->ctrl_dis = (1 << COLORS);
1247		gspca_dev->cam.bulk = 1;
1248		gspca_dev->cam.bulk_size = 16384;
1249		gspca_dev->cam.bulk_nurbs = 2;
1250		gspca_dev->cam.mode_framerates = ov772x_framerates;
1251	}
1252
1253	/* initialize */
1254	reg_w_array(gspca_dev, bridge_init[sd->sensor].val,
1255			bridge_init[sd->sensor].len);
1256	ov534_set_led(gspca_dev, 1);
1257	sccb_w_array(gspca_dev, sensor_init[sd->sensor].val,
1258			sensor_init[sd->sensor].len);
1259	if (sd->sensor == SENSOR_OV767x)
1260		sd_start(gspca_dev);
1261	sd_stopN(gspca_dev);
1262/*	set_frame_rate(gspca_dev);	*/
1263
1264	return gspca_dev->usb_err;
1265}
1266
1267static int sd_start(struct gspca_dev *gspca_dev)
1268{
1269	struct sd *sd = (struct sd *) gspca_dev;
1270	int mode;
1271	static const struct reg_array bridge_start[NSENSORS][2] = {
1272	[SENSOR_OV767x] = {{bridge_start_qvga_767x,
1273					ARRAY_SIZE(bridge_start_qvga_767x)},
1274			{bridge_start_vga_767x,
1275					ARRAY_SIZE(bridge_start_vga_767x)}},
1276	[SENSOR_OV772x] = {{bridge_start_qvga_772x,
1277					ARRAY_SIZE(bridge_start_qvga_772x)},
1278			{bridge_start_vga_772x,
1279					ARRAY_SIZE(bridge_start_vga_772x)}},
1280	};
1281	static const struct reg_array sensor_start[NSENSORS][2] = {
1282	[SENSOR_OV767x] = {{sensor_start_qvga_767x,
1283					ARRAY_SIZE(sensor_start_qvga_767x)},
1284			{sensor_start_vga_767x,
1285					ARRAY_SIZE(sensor_start_vga_767x)}},
1286	[SENSOR_OV772x] = {{sensor_start_qvga_772x,
1287					ARRAY_SIZE(sensor_start_qvga_772x)},
1288			{sensor_start_vga_772x,
1289					ARRAY_SIZE(sensor_start_vga_772x)}},
1290	};
1291
1292	/* (from ms-win trace) */
1293	if (sd->sensor == SENSOR_OV767x)
1294		sccb_reg_write(gspca_dev, 0x1e, 0x04);
1295					/* black sun enable ? */
1296
1297	mode = gspca_dev->curr_mode;	/* 0: 320x240, 1: 640x480 */
1298	reg_w_array(gspca_dev, bridge_start[sd->sensor][mode].val,
1299				bridge_start[sd->sensor][mode].len);
1300	sccb_w_array(gspca_dev, sensor_start[sd->sensor][mode].val,
1301				sensor_start[sd->sensor][mode].len);
1302
1303	set_frame_rate(gspca_dev);
1304
1305	if (!(gspca_dev->ctrl_dis & (1 << AGC)))
1306		setagc(gspca_dev);
1307	setawb(gspca_dev);
1308	setaec(gspca_dev);
1309	if (!(gspca_dev->ctrl_dis & (1 << GAIN)))
1310		setgain(gspca_dev);
1311	setexposure(gspca_dev);
1312	setbrightness(gspca_dev);
1313	setcontrast(gspca_dev);
1314	if (!(gspca_dev->ctrl_dis & (1 << SHARPNESS)))
1315		setsharpness(gspca_dev);
1316	sethvflip(gspca_dev);
1317	if (!(gspca_dev->ctrl_dis & (1 << COLORS)))
1318		setcolors(gspca_dev);
1319	setlightfreq(gspca_dev);
1320
1321	ov534_set_led(gspca_dev, 1);
1322	ov534_reg_write(gspca_dev, 0xe0, 0x00);
1323	return gspca_dev->usb_err;
1324}
1325
1326static void sd_stopN(struct gspca_dev *gspca_dev)
1327{
1328	ov534_reg_write(gspca_dev, 0xe0, 0x09);
1329	ov534_set_led(gspca_dev, 0);
1330}
1331
1332/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
1333#define UVC_STREAM_EOH	(1 << 7)
1334#define UVC_STREAM_ERR	(1 << 6)
1335#define UVC_STREAM_STI	(1 << 5)
1336#define UVC_STREAM_RES	(1 << 4)
1337#define UVC_STREAM_SCR	(1 << 3)
1338#define UVC_STREAM_PTS	(1 << 2)
1339#define UVC_STREAM_EOF	(1 << 1)
1340#define UVC_STREAM_FID	(1 << 0)
1341
1342static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1343			u8 *data, int len)
1344{
1345	struct sd *sd = (struct sd *) gspca_dev;
1346	__u32 this_pts;
1347	u16 this_fid;
1348	int remaining_len = len;
1349	int payload_len;
1350
1351	payload_len = gspca_dev->cam.bulk ? 2048 : 2040;
1352	do {
1353		len = min(remaining_len, payload_len);
1354
1355		/* Payloads are prefixed with a UVC-style header.  We
1356		   consider a frame to start when the FID toggles, or the PTS
1357		   changes.  A frame ends when EOF is set, and we've received
1358		   the correct number of bytes. */
1359
1360		/* Verify UVC header.  Header length is always 12 */
1361		if (data[0] != 12 || len < 12) {
1362			PDEBUG(D_PACK, "bad header");
1363			goto discard;
1364		}
1365
1366		/* Check errors */
1367		if (data[1] & UVC_STREAM_ERR) {
1368			PDEBUG(D_PACK, "payload error");
1369			goto discard;
1370		}
1371
1372		/* Extract PTS and FID */
1373		if (!(data[1] & UVC_STREAM_PTS)) {
1374			PDEBUG(D_PACK, "PTS not present");
1375			goto discard;
1376		}
1377		this_pts = (data[5] << 24) | (data[4] << 16)
1378						| (data[3] << 8) | data[2];
1379		this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0;
1380
1381		/* If PTS or FID has changed, start a new frame. */
1382		if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
1383			if (gspca_dev->last_packet_type == INTER_PACKET)
1384				gspca_frame_add(gspca_dev, LAST_PACKET,
1385						NULL, 0);
1386			sd->last_pts = this_pts;
1387			sd->last_fid = this_fid;
1388			gspca_frame_add(gspca_dev, FIRST_PACKET,
1389					data + 12, len - 12);
1390		/* If this packet is marked as EOF, end the frame */
1391		} else if (data[1] & UVC_STREAM_EOF) {
1392			sd->last_pts = 0;
1393			if (gspca_dev->pixfmt == V4L2_PIX_FMT_YUYV
1394			 && gspca_dev->image_len + len - 12 !=
1395				   gspca_dev->width * gspca_dev->height * 2) {
1396				PDEBUG(D_PACK, "wrong sized frame");
1397				goto discard;
1398			}
1399			gspca_frame_add(gspca_dev, LAST_PACKET,
1400					data + 12, len - 12);
1401		} else {
1402
1403			/* Add the data from this payload */
1404			gspca_frame_add(gspca_dev, INTER_PACKET,
1405					data + 12, len - 12);
1406		}
1407
1408		/* Done this payload */
1409		goto scan_next;
1410
1411discard:
1412		/* Discard data until a new frame starts. */
1413		gspca_dev->last_packet_type = DISCARD_PACKET;
1414
1415scan_next:
1416		remaining_len -= len;
1417		data += len;
1418	} while (remaining_len > 0);
1419}
1420
1421static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val)
1422{
1423	struct sd *sd = (struct sd *) gspca_dev;
1424
1425	sd->ctrls[AGC].val = val;
1426
1427	/* the auto white balance control works only
1428	 * when auto gain is set */
1429	if (val) {
1430		gspca_dev->ctrl_inac &= ~(1 << AWB);
1431	} else {
1432		gspca_dev->ctrl_inac |= (1 << AWB);
1433		if (sd->ctrls[AWB].val) {
1434			sd->ctrls[AWB].val = 0;
1435			if (gspca_dev->streaming)
1436				setawb(gspca_dev);
1437		}
1438	}
1439	if (gspca_dev->streaming)
1440		setagc(gspca_dev);
1441	return gspca_dev->usb_err;
1442}
1443
1444static int sd_querymenu(struct gspca_dev *gspca_dev,
1445		struct v4l2_querymenu *menu)
1446{
1447	switch (menu->id) {
1448	case V4L2_CID_POWER_LINE_FREQUENCY:
1449		switch (menu->index) {
1450		case 0:         /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1451			strcpy((char *) menu->name, "Disabled");
1452			return 0;
1453		case 1:         /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1454			strcpy((char *) menu->name, "50 Hz");
1455			return 0;
1456		}
1457		break;
1458	}
1459
1460	return -EINVAL;
1461}
1462
1463/* get stream parameters (framerate) */
1464static void sd_get_streamparm(struct gspca_dev *gspca_dev,
1465			     struct v4l2_streamparm *parm)
1466{
1467	struct v4l2_captureparm *cp = &parm->parm.capture;
1468	struct v4l2_fract *tpf = &cp->timeperframe;
1469	struct sd *sd = (struct sd *) gspca_dev;
1470
1471	cp->capability |= V4L2_CAP_TIMEPERFRAME;
1472	tpf->numerator = 1;
1473	tpf->denominator = sd->frame_rate;
1474}
1475
1476/* set stream parameters (framerate) */
1477static void sd_set_streamparm(struct gspca_dev *gspca_dev,
1478			     struct v4l2_streamparm *parm)
1479{
1480	struct v4l2_captureparm *cp = &parm->parm.capture;
1481	struct v4l2_fract *tpf = &cp->timeperframe;
1482	struct sd *sd = (struct sd *) gspca_dev;
1483
1484	/* Set requested framerate */
1485	sd->frame_rate = tpf->denominator / tpf->numerator;
1486	if (gspca_dev->streaming)
1487		set_frame_rate(gspca_dev);
1488
1489	/* Return the actual framerate */
1490	tpf->numerator = 1;
1491	tpf->denominator = sd->frame_rate;
1492}
1493
1494/* sub-driver description */
1495static const struct sd_desc sd_desc = {
1496	.name     = MODULE_NAME,
1497	.ctrls    = sd_ctrls,
1498	.nctrls   = ARRAY_SIZE(sd_ctrls),
1499	.config   = sd_config,
1500	.init     = sd_init,
1501	.start    = sd_start,
1502	.stopN    = sd_stopN,
1503	.pkt_scan = sd_pkt_scan,
1504	.querymenu = sd_querymenu,
1505	.get_streamparm = sd_get_streamparm,
1506	.set_streamparm = sd_set_streamparm,
1507};
1508
1509/* -- module initialisation -- */
1510static const struct usb_device_id device_table[] = {
1511	{USB_DEVICE(0x1415, 0x2000)},
1512	{USB_DEVICE(0x06f8, 0x3002)},
1513	{}
1514};
1515
1516MODULE_DEVICE_TABLE(usb, device_table);
1517
1518/* -- device connect -- */
1519static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id)
1520{
1521	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1522				THIS_MODULE);
1523}
1524
1525static struct usb_driver sd_driver = {
1526	.name       = MODULE_NAME,
1527	.id_table   = device_table,
1528	.probe      = sd_probe,
1529	.disconnect = gspca_disconnect,
1530#ifdef CONFIG_PM
1531	.suspend    = gspca_suspend,
1532	.resume     = gspca_resume,
1533#endif
1534};
1535
1536module_usb_driver(sd_driver);
1537