1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 *	Sonix sn9c201 sn9c202 library
4 *
5 * Copyright (C) 2012 Jean-Francois Moine <http://moinejf.free.fr>
6 *	Copyright (C) 2008-2009 microdia project <microdia@googlegroups.com>
7 *	Copyright (C) 2009 Brian Johnson <brijohn@gmail.com>
8 */
9
10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11
12#include <linux/input.h>
13
14#include "gspca.h"
15#include "jpeg.h"
16
17#include <linux/dmi.h>
18
19MODULE_AUTHOR("Brian Johnson <brijohn@gmail.com>, microdia project <microdia@googlegroups.com>");
20MODULE_DESCRIPTION("GSPCA/SN9C20X USB Camera Driver");
21MODULE_LICENSE("GPL");
22
23/*
24 * Pixel format private data
25 */
26#define SCALE_MASK	0x0f
27#define SCALE_160x120	0
28#define SCALE_320x240	1
29#define SCALE_640x480	2
30#define SCALE_1280x1024	3
31#define MODE_RAW	0x10
32#define MODE_JPEG	0x20
33#define MODE_SXGA	0x80
34
35#define SENSOR_OV9650	0
36#define SENSOR_OV9655	1
37#define SENSOR_SOI968	2
38#define SENSOR_OV7660	3
39#define SENSOR_OV7670	4
40#define SENSOR_MT9V011	5
41#define SENSOR_MT9V111	6
42#define SENSOR_MT9V112	7
43#define SENSOR_MT9M001	8
44#define SENSOR_MT9M111	9
45#define SENSOR_MT9M112  10
46#define SENSOR_HV7131R	11
47#define SENSOR_MT9VPRB	12
48
49/* camera flags */
50#define HAS_NO_BUTTON	0x1
51#define LED_REVERSE	0x2 /* some cameras unset gpio to turn on leds */
52#define FLIP_DETECT	0x4
53#define HAS_LED_TORCH	0x8
54
55/* specific webcam descriptor */
56struct sd {
57	struct gspca_dev gspca_dev;
58
59	struct { /* color control cluster */
60		struct v4l2_ctrl *brightness;
61		struct v4l2_ctrl *contrast;
62		struct v4l2_ctrl *saturation;
63		struct v4l2_ctrl *hue;
64	};
65	struct { /* blue/red balance control cluster */
66		struct v4l2_ctrl *blue;
67		struct v4l2_ctrl *red;
68	};
69	struct { /* h/vflip control cluster */
70		struct v4l2_ctrl *hflip;
71		struct v4l2_ctrl *vflip;
72	};
73	struct v4l2_ctrl *gamma;
74	struct { /* autogain and exposure or gain control cluster */
75		struct v4l2_ctrl *autogain;
76		struct v4l2_ctrl *exposure;
77		struct v4l2_ctrl *gain;
78	};
79	struct v4l2_ctrl *jpegqual;
80
81	struct v4l2_ctrl *led_mode;
82
83	struct work_struct work;
84
85	u32 pktsz;			/* (used by pkt_scan) */
86	u16 npkt;
87	s8 nchg;
88	u8 fmt;				/* (used for JPEG QTAB update */
89
90#define MIN_AVG_LUM 80
91#define MAX_AVG_LUM 130
92	atomic_t avg_lum;
93	u8 old_step;
94	u8 older_step;
95	u8 exposure_step;
96
97	u8 i2c_addr;
98	u8 i2c_intf;
99	u8 sensor;
100	u8 hstart;
101	u8 vstart;
102
103	u8 jpeg_hdr[JPEG_HDR_SZ];
104
105	u8 flags;
106};
107
108static void qual_upd(struct work_struct *work);
109
110struct i2c_reg_u8 {
111	u8 reg;
112	u8 val;
113};
114
115struct i2c_reg_u16 {
116	u8 reg;
117	u16 val;
118};
119
120static const struct dmi_system_id flip_dmi_table[] = {
121	{
122		.ident = "MSI MS-1034",
123		.matches = {
124			DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
125			DMI_MATCH(DMI_PRODUCT_NAME, "MS-1034"),
126			DMI_MATCH(DMI_PRODUCT_VERSION, "0341")
127		}
128	},
129	{
130		.ident = "MSI MS-1039",
131		.matches = {
132			DMI_MATCH(DMI_SYS_VENDOR, "MICRO-STAR INT'L CO.,LTD."),
133			DMI_MATCH(DMI_PRODUCT_NAME, "MS-1039"),
134		}
135	},
136	{
137		.ident = "MSI MS-1632",
138		.matches = {
139			DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
140			DMI_MATCH(DMI_BOARD_NAME, "MS-1632")
141		}
142	},
143	{
144		.ident = "MSI MS-1633X",
145		.matches = {
146			DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
147			DMI_MATCH(DMI_BOARD_NAME, "MS-1633X")
148		}
149	},
150	{
151		.ident = "MSI MS-1635X",
152		.matches = {
153			DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
154			DMI_MATCH(DMI_BOARD_NAME, "MS-1635X")
155		}
156	},
157	{
158		.ident = "ASUSTeK W7J",
159		.matches = {
160			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc."),
161			DMI_MATCH(DMI_BOARD_NAME, "W7J       ")
162		}
163	},
164	{}
165};
166
167static const struct v4l2_pix_format vga_mode[] = {
168	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
169		.bytesperline = 160,
170		.sizeimage = 160 * 120 * 4 / 8 + 590,
171		.colorspace = V4L2_COLORSPACE_JPEG,
172		.priv = SCALE_160x120 | MODE_JPEG},
173	{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
174		.bytesperline = 160,
175		.sizeimage = 160 * 120,
176		.colorspace = V4L2_COLORSPACE_SRGB,
177		.priv = SCALE_160x120 | MODE_RAW},
178	{160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
179		.bytesperline = 160,
180		.sizeimage = 240 * 120,
181		.colorspace = V4L2_COLORSPACE_SRGB,
182		.priv = SCALE_160x120},
183	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
184		.bytesperline = 320,
185		.sizeimage = 320 * 240 * 4 / 8 + 590,
186		.colorspace = V4L2_COLORSPACE_JPEG,
187		.priv = SCALE_320x240 | MODE_JPEG},
188	{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
189		.bytesperline = 320,
190		.sizeimage = 320 * 240 ,
191		.colorspace = V4L2_COLORSPACE_SRGB,
192		.priv = SCALE_320x240 | MODE_RAW},
193	{320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
194		.bytesperline = 320,
195		.sizeimage = 480 * 240 ,
196		.colorspace = V4L2_COLORSPACE_SRGB,
197		.priv = SCALE_320x240},
198	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
199		.bytesperline = 640,
200		.sizeimage = 640 * 480 * 4 / 8 + 590,
201		.colorspace = V4L2_COLORSPACE_JPEG,
202		.priv = SCALE_640x480 | MODE_JPEG},
203	{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
204		.bytesperline = 640,
205		.sizeimage = 640 * 480,
206		.colorspace = V4L2_COLORSPACE_SRGB,
207		.priv = SCALE_640x480 | MODE_RAW},
208	{640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
209		.bytesperline = 640,
210		.sizeimage = 960 * 480,
211		.colorspace = V4L2_COLORSPACE_SRGB,
212		.priv = SCALE_640x480},
213};
214
215static const struct v4l2_pix_format sxga_mode[] = {
216	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
217		.bytesperline = 160,
218		.sizeimage = 160 * 120 * 4 / 8 + 590,
219		.colorspace = V4L2_COLORSPACE_JPEG,
220		.priv = SCALE_160x120 | MODE_JPEG},
221	{160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
222		.bytesperline = 160,
223		.sizeimage = 160 * 120,
224		.colorspace = V4L2_COLORSPACE_SRGB,
225		.priv = SCALE_160x120 | MODE_RAW},
226	{160, 120, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
227		.bytesperline = 160,
228		.sizeimage = 240 * 120,
229		.colorspace = V4L2_COLORSPACE_SRGB,
230		.priv = SCALE_160x120},
231	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
232		.bytesperline = 320,
233		.sizeimage = 320 * 240 * 4 / 8 + 590,
234		.colorspace = V4L2_COLORSPACE_JPEG,
235		.priv = SCALE_320x240 | MODE_JPEG},
236	{320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
237		.bytesperline = 320,
238		.sizeimage = 320 * 240 ,
239		.colorspace = V4L2_COLORSPACE_SRGB,
240		.priv = SCALE_320x240 | MODE_RAW},
241	{320, 240, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
242		.bytesperline = 320,
243		.sizeimage = 480 * 240 ,
244		.colorspace = V4L2_COLORSPACE_SRGB,
245		.priv = SCALE_320x240},
246	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
247		.bytesperline = 640,
248		.sizeimage = 640 * 480 * 4 / 8 + 590,
249		.colorspace = V4L2_COLORSPACE_JPEG,
250		.priv = SCALE_640x480 | MODE_JPEG},
251	{640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
252		.bytesperline = 640,
253		.sizeimage = 640 * 480,
254		.colorspace = V4L2_COLORSPACE_SRGB,
255		.priv = SCALE_640x480 | MODE_RAW},
256	{640, 480, V4L2_PIX_FMT_SN9C20X_I420, V4L2_FIELD_NONE,
257		.bytesperline = 640,
258		.sizeimage = 960 * 480,
259		.colorspace = V4L2_COLORSPACE_SRGB,
260		.priv = SCALE_640x480},
261	{1280, 1024, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
262		.bytesperline = 1280,
263		.sizeimage = 1280 * 1024,
264		.colorspace = V4L2_COLORSPACE_SRGB,
265		.priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
266};
267
268static const struct v4l2_pix_format mono_mode[] = {
269	{160, 120, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
270		.bytesperline = 160,
271		.sizeimage = 160 * 120,
272		.colorspace = V4L2_COLORSPACE_SRGB,
273		.priv = SCALE_160x120 | MODE_RAW},
274	{320, 240, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
275		.bytesperline = 320,
276		.sizeimage = 320 * 240 ,
277		.colorspace = V4L2_COLORSPACE_SRGB,
278		.priv = SCALE_320x240 | MODE_RAW},
279	{640, 480, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
280		.bytesperline = 640,
281		.sizeimage = 640 * 480,
282		.colorspace = V4L2_COLORSPACE_SRGB,
283		.priv = SCALE_640x480 | MODE_RAW},
284	{1280, 1024, V4L2_PIX_FMT_GREY, V4L2_FIELD_NONE,
285		.bytesperline = 1280,
286		.sizeimage = 1280 * 1024,
287		.colorspace = V4L2_COLORSPACE_SRGB,
288		.priv = SCALE_1280x1024 | MODE_RAW | MODE_SXGA},
289};
290
291static const s16 hsv_red_x[] = {
292	41,  44,  46,  48,  50,  52,  54,  56,
293	58,  60,  62,  64,  66,  68,  70,  72,
294	74,  76,  78,  80,  81,  83,  85,  87,
295	88,  90,  92,  93,  95,  97,  98, 100,
296	101, 102, 104, 105, 107, 108, 109, 110,
297	112, 113, 114, 115, 116, 117, 118, 119,
298	120, 121, 122, 123, 123, 124, 125, 125,
299	126, 127, 127, 128, 128, 129, 129, 129,
300	130, 130, 130, 130, 131, 131, 131, 131,
301	131, 131, 131, 131, 130, 130, 130, 130,
302	129, 129, 129, 128, 128, 127, 127, 126,
303	125, 125, 124, 123, 122, 122, 121, 120,
304	119, 118, 117, 116, 115, 114, 112, 111,
305	110, 109, 107, 106, 105, 103, 102, 101,
306	99,  98,  96,  94,  93,  91,  90,  88,
307	86,  84,  83,  81,  79,  77,  75,  74,
308	72,  70,  68,  66,  64,  62,  60,  58,
309	56,  54,  52,  49,  47,  45,  43,  41,
310	39,  36,  34,  32,  30,  28,  25,  23,
311	21,  19,  16,  14,  12,   9,   7,   5,
312	3,   0,  -1,  -3,  -6,  -8, -10, -12,
313	-15, -17, -19, -22, -24, -26, -28, -30,
314	-33, -35, -37, -39, -41, -44, -46, -48,
315	-50, -52, -54, -56, -58, -60, -62, -64,
316	-66, -68, -70, -72, -74, -76, -78, -80,
317	-81, -83, -85, -87, -88, -90, -92, -93,
318	-95, -97, -98, -100, -101, -102, -104, -105,
319	-107, -108, -109, -110, -112, -113, -114, -115,
320	-116, -117, -118, -119, -120, -121, -122, -123,
321	-123, -124, -125, -125, -126, -127, -127, -128,
322	-128, -128, -128, -128, -128, -128, -128, -128,
323	-128, -128, -128, -128, -128, -128, -128, -128,
324	-128, -128, -128, -128, -128, -128, -128, -128,
325	-128, -127, -127, -126, -125, -125, -124, -123,
326	-122, -122, -121, -120, -119, -118, -117, -116,
327	-115, -114, -112, -111, -110, -109, -107, -106,
328	-105, -103, -102, -101, -99, -98, -96, -94,
329	-93, -91, -90, -88, -86, -84, -83, -81,
330	-79, -77, -75, -74, -72, -70, -68, -66,
331	-64, -62, -60, -58, -56, -54, -52, -49,
332	-47, -45, -43, -41, -39, -36, -34, -32,
333	-30, -28, -25, -23, -21, -19, -16, -14,
334	-12,  -9,  -7,  -5,  -3,   0,   1,   3,
335	6,   8,  10,  12,  15,  17,  19,  22,
336	24,  26,  28,  30,  33,  35,  37,  39, 41
337};
338
339static const s16 hsv_red_y[] = {
340	82,  80,  78,  76,  74,  73,  71,  69,
341	67,  65,  63,  61,  58,  56,  54,  52,
342	50,  48,  46,  44,  41,  39,  37,  35,
343	32,  30,  28,  26,  23,  21,  19,  16,
344	14,  12,  10,   7,   5,   3,   0,  -1,
345	-3,  -6,  -8, -10, -13, -15, -17, -19,
346	-22, -24, -26, -29, -31, -33, -35, -38,
347	-40, -42, -44, -46, -48, -51, -53, -55,
348	-57, -59, -61, -63, -65, -67, -69, -71,
349	-73, -75, -77, -79, -81, -82, -84, -86,
350	-88, -89, -91, -93, -94, -96, -98, -99,
351	-101, -102, -104, -105, -106, -108, -109, -110,
352	-112, -113, -114, -115, -116, -117, -119, -120,
353	-120, -121, -122, -123, -124, -125, -126, -126,
354	-127, -128, -128, -128, -128, -128, -128, -128,
355	-128, -128, -128, -128, -128, -128, -128, -128,
356	-128, -128, -128, -128, -128, -128, -128, -128,
357	-128, -128, -128, -128, -128, -128, -128, -128,
358	-127, -127, -126, -125, -125, -124, -123, -122,
359	-121, -120, -119, -118, -117, -116, -115, -114,
360	-113, -111, -110, -109, -107, -106, -105, -103,
361	-102, -100, -99, -97, -96, -94, -92, -91,
362	-89, -87, -85, -84, -82, -80, -78, -76,
363	-74, -73, -71, -69, -67, -65, -63, -61,
364	-58, -56, -54, -52, -50, -48, -46, -44,
365	-41, -39, -37, -35, -32, -30, -28, -26,
366	-23, -21, -19, -16, -14, -12, -10,  -7,
367	-5,  -3,   0,   1,   3,   6,   8,  10,
368	13,  15,  17,  19,  22,  24,  26,  29,
369	31,  33,  35,  38,  40,  42,  44,  46,
370	48,  51,  53,  55,  57,  59,  61,  63,
371	65,  67,  69,  71,  73,  75,  77,  79,
372	81,  82,  84,  86,  88,  89,  91,  93,
373	94,  96,  98,  99, 101, 102, 104, 105,
374	106, 108, 109, 110, 112, 113, 114, 115,
375	116, 117, 119, 120, 120, 121, 122, 123,
376	124, 125, 126, 126, 127, 128, 128, 129,
377	129, 130, 130, 131, 131, 131, 131, 132,
378	132, 132, 132, 132, 132, 132, 132, 132,
379	132, 132, 132, 131, 131, 131, 130, 130,
380	130, 129, 129, 128, 127, 127, 126, 125,
381	125, 124, 123, 122, 121, 120, 119, 118,
382	117, 116, 115, 114, 113, 111, 110, 109,
383	107, 106, 105, 103, 102, 100,  99,  97,
384	96, 94, 92, 91, 89, 87, 85, 84, 82
385};
386
387static const s16 hsv_green_x[] = {
388	-124, -124, -125, -125, -125, -125, -125, -125,
389	-125, -126, -126, -125, -125, -125, -125, -125,
390	-125, -124, -124, -124, -123, -123, -122, -122,
391	-121, -121, -120, -120, -119, -118, -117, -117,
392	-116, -115, -114, -113, -112, -111, -110, -109,
393	-108, -107, -105, -104, -103, -102, -100, -99,
394	-98, -96, -95, -93, -92, -91, -89, -87,
395	-86, -84, -83, -81, -79, -77, -76, -74,
396	-72, -70, -69, -67, -65, -63, -61, -59,
397	-57, -55, -53, -51, -49, -47, -45, -43,
398	-41, -39, -37, -35, -33, -30, -28, -26,
399	-24, -22, -20, -18, -15, -13, -11,  -9,
400	-7,  -4,  -2,   0,   1,   3,   6,   8,
401	10,  12,  14,  17,  19,  21,  23,  25,
402	27,  29,  32,  34,  36,  38,  40,  42,
403	44,  46,  48,  50,  52,  54,  56,  58,
404	60,  62,  64,  66,  68,  70,  71,  73,
405	75,  77,  78,  80,  82,  83,  85,  87,
406	88,  90,  91,  93,  94,  96,  97,  98,
407	100, 101, 102, 104, 105, 106, 107, 108,
408	109, 111, 112, 113, 113, 114, 115, 116,
409	117, 118, 118, 119, 120, 120, 121, 122,
410	122, 123, 123, 124, 124, 124, 125, 125,
411	125, 125, 125, 125, 125, 126, 126, 125,
412	125, 125, 125, 125, 125, 124, 124, 124,
413	123, 123, 122, 122, 121, 121, 120, 120,
414	119, 118, 117, 117, 116, 115, 114, 113,
415	112, 111, 110, 109, 108, 107, 105, 104,
416	103, 102, 100,  99,  98,  96,  95,  93,
417	92,  91,  89,  87,  86,  84,  83,  81,
418	79,  77,  76,  74,  72,  70,  69,  67,
419	65,  63,  61,  59,  57,  55,  53,  51,
420	49,  47,  45,  43,  41,  39,  37,  35,
421	33,  30,  28,  26,  24,  22,  20,  18,
422	15,  13,  11,   9,   7,   4,   2,   0,
423	-1,  -3,  -6,  -8, -10, -12, -14, -17,
424	-19, -21, -23, -25, -27, -29, -32, -34,
425	-36, -38, -40, -42, -44, -46, -48, -50,
426	-52, -54, -56, -58, -60, -62, -64, -66,
427	-68, -70, -71, -73, -75, -77, -78, -80,
428	-82, -83, -85, -87, -88, -90, -91, -93,
429	-94, -96, -97, -98, -100, -101, -102, -104,
430	-105, -106, -107, -108, -109, -111, -112, -113,
431	-113, -114, -115, -116, -117, -118, -118, -119,
432	-120, -120, -121, -122, -122, -123, -123, -124, -124
433};
434
435static const s16 hsv_green_y[] = {
436	-100, -99, -98, -97, -95, -94, -93, -91,
437	-90, -89, -87, -86, -84, -83, -81, -80,
438	-78, -76, -75, -73, -71, -70, -68, -66,
439	-64, -63, -61, -59, -57, -55, -53, -51,
440	-49, -48, -46, -44, -42, -40, -38, -36,
441	-34, -32, -30, -27, -25, -23, -21, -19,
442	-17, -15, -13, -11,  -9,  -7,  -4,  -2,
443	0,   1,   3,   5,   7,   9,  11,  14,
444	16,  18,  20,  22,  24,  26,  28,  30,
445	32,  34,  36,  38,  40,  42,  44,  46,
446	48,  50,  52,  54,  56,  58,  59,  61,
447	63,  65,  67,  68,  70,  72,  74,  75,
448	77,  78,  80,  82,  83,  85,  86,  88,
449	89,  90,  92,  93,  95,  96,  97,  98,
450	100, 101, 102, 103, 104, 105, 106, 107,
451	108, 109, 110, 111, 112, 112, 113, 114,
452	115, 115, 116, 116, 117, 117, 118, 118,
453	119, 119, 119, 120, 120, 120, 120, 120,
454	121, 121, 121, 121, 121, 121, 120, 120,
455	120, 120, 120, 119, 119, 119, 118, 118,
456	117, 117, 116, 116, 115, 114, 114, 113,
457	112, 111, 111, 110, 109, 108, 107, 106,
458	105, 104, 103, 102, 100,  99,  98,  97,
459	95,  94,  93,  91,  90,  89,  87,  86,
460	84,  83,  81,  80,  78,  76,  75,  73,
461	71,  70,  68,  66,  64,  63,  61,  59,
462	57,  55,  53,  51,  49,  48,  46,  44,
463	42,  40,  38,  36,  34,  32,  30,  27,
464	25,  23,  21,  19,  17,  15,  13,  11,
465	9,   7,   4,   2,   0,  -1,  -3,  -5,
466	-7,  -9, -11, -14, -16, -18, -20, -22,
467	-24, -26, -28, -30, -32, -34, -36, -38,
468	-40, -42, -44, -46, -48, -50, -52, -54,
469	-56, -58, -59, -61, -63, -65, -67, -68,
470	-70, -72, -74, -75, -77, -78, -80, -82,
471	-83, -85, -86, -88, -89, -90, -92, -93,
472	-95, -96, -97, -98, -100, -101, -102, -103,
473	-104, -105, -106, -107, -108, -109, -110, -111,
474	-112, -112, -113, -114, -115, -115, -116, -116,
475	-117, -117, -118, -118, -119, -119, -119, -120,
476	-120, -120, -120, -120, -121, -121, -121, -121,
477	-121, -121, -120, -120, -120, -120, -120, -119,
478	-119, -119, -118, -118, -117, -117, -116, -116,
479	-115, -114, -114, -113, -112, -111, -111, -110,
480	-109, -108, -107, -106, -105, -104, -103, -102, -100
481};
482
483static const s16 hsv_blue_x[] = {
484	112, 113, 114, 114, 115, 116, 117, 117,
485	118, 118, 119, 119, 120, 120, 120, 121,
486	121, 121, 122, 122, 122, 122, 122, 122,
487	122, 122, 122, 122, 122, 122, 121, 121,
488	121, 120, 120, 120, 119, 119, 118, 118,
489	117, 116, 116, 115, 114, 113, 113, 112,
490	111, 110, 109, 108, 107, 106, 105, 104,
491	103, 102, 100,  99,  98,  97,  95,  94,
492	93,  91,  90,  88,  87,  85,  84,  82,
493	80,  79,  77,  76,  74,  72,  70,  69,
494	67,  65,  63,  61,  60,  58,  56,  54,
495	52,  50,  48,  46,  44,  42,  40,  38,
496	36,  34,  32,  30,  28,  26,  24,  22,
497	19,  17,  15,  13,  11,   9,   7,   5,
498	2,   0,  -1,  -3,  -5,  -7,  -9, -12,
499	-14, -16, -18, -20, -22, -24, -26, -28,
500	-31, -33, -35, -37, -39, -41, -43, -45,
501	-47, -49, -51, -53, -54, -56, -58, -60,
502	-62, -64, -66, -67, -69, -71, -73, -74,
503	-76, -78, -79, -81, -83, -84, -86, -87,
504	-89, -90, -92, -93, -94, -96, -97, -98,
505	-99, -101, -102, -103, -104, -105, -106, -107,
506	-108, -109, -110, -111, -112, -113, -114, -114,
507	-115, -116, -117, -117, -118, -118, -119, -119,
508	-120, -120, -120, -121, -121, -121, -122, -122,
509	-122, -122, -122, -122, -122, -122, -122, -122,
510	-122, -122, -121, -121, -121, -120, -120, -120,
511	-119, -119, -118, -118, -117, -116, -116, -115,
512	-114, -113, -113, -112, -111, -110, -109, -108,
513	-107, -106, -105, -104, -103, -102, -100, -99,
514	-98, -97, -95, -94, -93, -91, -90, -88,
515	-87, -85, -84, -82, -80, -79, -77, -76,
516	-74, -72, -70, -69, -67, -65, -63, -61,
517	-60, -58, -56, -54, -52, -50, -48, -46,
518	-44, -42, -40, -38, -36, -34, -32, -30,
519	-28, -26, -24, -22, -19, -17, -15, -13,
520	-11,  -9,  -7,  -5,  -2,   0,   1,   3,
521	5,   7,   9,  12,  14,  16,  18,  20,
522	22,  24,  26,  28,  31,  33,  35,  37,
523	39,  41,  43,  45,  47,  49,  51,  53,
524	54,  56,  58,  60,  62,  64,  66,  67,
525	69,  71,  73,  74,  76,  78,  79,  81,
526	83,  84,  86,  87,  89,  90,  92,  93,
527	94,  96,  97,  98,  99, 101, 102, 103,
528	104, 105, 106, 107, 108, 109, 110, 111, 112
529};
530
531static const s16 hsv_blue_y[] = {
532	-11, -13, -15, -17, -19, -21, -23, -25,
533	-27, -29, -31, -33, -35, -37, -39, -41,
534	-43, -45, -46, -48, -50, -52, -54, -55,
535	-57, -59, -61, -62, -64, -66, -67, -69,
536	-71, -72, -74, -75, -77, -78, -80, -81,
537	-83, -84, -86, -87, -88, -90, -91, -92,
538	-93, -95, -96, -97, -98, -99, -100, -101,
539	-102, -103, -104, -105, -106, -106, -107, -108,
540	-109, -109, -110, -111, -111, -112, -112, -113,
541	-113, -114, -114, -114, -115, -115, -115, -115,
542	-116, -116, -116, -116, -116, -116, -116, -116,
543	-116, -115, -115, -115, -115, -114, -114, -114,
544	-113, -113, -112, -112, -111, -111, -110, -110,
545	-109, -108, -108, -107, -106, -105, -104, -103,
546	-102, -101, -100, -99, -98, -97, -96, -95,
547	-94, -93, -91, -90, -89, -88, -86, -85,
548	-84, -82, -81, -79, -78, -76, -75, -73,
549	-71, -70, -68, -67, -65, -63, -62, -60,
550	-58, -56, -55, -53, -51, -49, -47, -45,
551	-44, -42, -40, -38, -36, -34, -32, -30,
552	-28, -26, -24, -22, -20, -18, -16, -14,
553	-12, -10,  -8,  -6,  -4,  -2,   0,   1,
554	3,   5,   7,   9,  11,  13,  15,  17,
555	19,  21,  23,  25,  27,  29,  31,  33,
556	35,  37,  39,  41,  43,  45,  46,  48,
557	50,  52,  54,  55,  57,  59,  61,  62,
558	64,  66,  67,  69,  71,  72,  74,  75,
559	77,  78,  80,  81,  83,  84,  86,  87,
560	88,  90,  91,  92,  93,  95,  96,  97,
561	98,  99, 100, 101, 102, 103, 104, 105,
562	106, 106, 107, 108, 109, 109, 110, 111,
563	111, 112, 112, 113, 113, 114, 114, 114,
564	115, 115, 115, 115, 116, 116, 116, 116,
565	116, 116, 116, 116, 116, 115, 115, 115,
566	115, 114, 114, 114, 113, 113, 112, 112,
567	111, 111, 110, 110, 109, 108, 108, 107,
568	106, 105, 104, 103, 102, 101, 100,  99,
569	98,  97,  96,  95,  94,  93,  91,  90,
570	89,  88,  86,  85,  84,  82,  81,  79,
571	78,  76,  75,  73,  71,  70,  68,  67,
572	65,  63,  62,  60,  58,  56,  55,  53,
573	51,  49,  47,  45,  44,  42,  40,  38,
574	36,  34,  32,  30,  28,  26,  24,  22,
575	20,  18,  16,  14,  12,  10,   8,   6,
576	4,   2,   0,  -1,  -3,  -5,  -7,  -9, -11
577};
578
579static const u16 bridge_init[][2] = {
580	{0x1000, 0x78}, {0x1001, 0x40}, {0x1002, 0x1c},
581	{0x1020, 0x80}, {0x1061, 0x01}, {0x1067, 0x40},
582	{0x1068, 0x30}, {0x1069, 0x20},	{0x106a, 0x10},
583	{0x106b, 0x08},	{0x1188, 0x87},	{0x11a1, 0x00},
584	{0x11a2, 0x00},	{0x11a3, 0x6a},	{0x11a4, 0x50},
585	{0x11ab, 0x00},	{0x11ac, 0x00},	{0x11ad, 0x50},
586	{0x11ae, 0x3c},	{0x118a, 0x04},	{0x0395, 0x04},
587	{0x11b8, 0x3a},	{0x118b, 0x0e},	{0x10f7, 0x05},
588	{0x10f8, 0x14},	{0x10fa, 0xff},	{0x10f9, 0x00},
589	{0x11ba, 0x0a},	{0x11a5, 0x2d},	{0x11a6, 0x2d},
590	{0x11a7, 0x3a},	{0x11a8, 0x05},	{0x11a9, 0x04},
591	{0x11aa, 0x3f},	{0x11af, 0x28},	{0x11b0, 0xd8},
592	{0x11b1, 0x14},	{0x11b2, 0xec},	{0x11b3, 0x32},
593	{0x11b4, 0xdd},	{0x11b5, 0x32},	{0x11b6, 0xdd},
594	{0x10e0, 0x2c},	{0x11bc, 0x40},	{0x11bd, 0x01},
595	{0x11be, 0xf0},	{0x11bf, 0x00},	{0x118c, 0x1f},
596	{0x118d, 0x1f},	{0x118e, 0x1f},	{0x118f, 0x1f},
597	{0x1180, 0x01},	{0x1181, 0x00},	{0x1182, 0x01},
598	{0x1183, 0x00},	{0x1184, 0x50},	{0x1185, 0x80},
599	{0x1007, 0x00}
600};
601
602/* Gain = (bit[3:0] / 16 + 1) * (bit[4] + 1) * (bit[5] + 1) * (bit[6] + 1) */
603static const u8 ov_gain[] = {
604	0x00 /* 1x */, 0x04 /* 1.25x */, 0x08 /* 1.5x */, 0x0c /* 1.75x */,
605	0x10 /* 2x */, 0x12 /* 2.25x */, 0x14 /* 2.5x */, 0x16 /* 2.75x */,
606	0x18 /* 3x */, 0x1a /* 3.25x */, 0x1c /* 3.5x */, 0x1e /* 3.75x */,
607	0x30 /* 4x */, 0x31 /* 4.25x */, 0x32 /* 4.5x */, 0x33 /* 4.75x */,
608	0x34 /* 5x */, 0x35 /* 5.25x */, 0x36 /* 5.5x */, 0x37 /* 5.75x */,
609	0x38 /* 6x */, 0x39 /* 6.25x */, 0x3a /* 6.5x */, 0x3b /* 6.75x */,
610	0x3c /* 7x */, 0x3d /* 7.25x */, 0x3e /* 7.5x */, 0x3f /* 7.75x */,
611	0x70 /* 8x */
612};
613
614/* Gain = (bit[8] + 1) * (bit[7] + 1) * (bit[6:0] * 0.03125) */
615static const u16 micron1_gain[] = {
616	/* 1x   1.25x   1.5x    1.75x */
617	0x0020, 0x0028, 0x0030, 0x0038,
618	/* 2x   2.25x   2.5x    2.75x */
619	0x00a0, 0x00a4, 0x00a8, 0x00ac,
620	/* 3x   3.25x   3.5x    3.75x */
621	0x00b0, 0x00b4, 0x00b8, 0x00bc,
622	/* 4x   4.25x   4.5x    4.75x */
623	0x00c0, 0x00c4, 0x00c8, 0x00cc,
624	/* 5x   5.25x   5.5x    5.75x */
625	0x00d0, 0x00d4, 0x00d8, 0x00dc,
626	/* 6x   6.25x   6.5x    6.75x */
627	0x00e0, 0x00e4, 0x00e8, 0x00ec,
628	/* 7x   7.25x   7.5x    7.75x */
629	0x00f0, 0x00f4, 0x00f8, 0x00fc,
630	/* 8x */
631	0x01c0
632};
633
634/* mt9m001 sensor uses a different gain formula then other micron sensors */
635/* Gain = (bit[6] + 1) * (bit[5-0] * 0.125) */
636static const u16 micron2_gain[] = {
637	/* 1x   1.25x   1.5x    1.75x */
638	0x0008, 0x000a, 0x000c, 0x000e,
639	/* 2x   2.25x   2.5x    2.75x */
640	0x0010, 0x0012, 0x0014, 0x0016,
641	/* 3x   3.25x   3.5x    3.75x */
642	0x0018, 0x001a, 0x001c, 0x001e,
643	/* 4x   4.25x   4.5x    4.75x */
644	0x0020, 0x0051, 0x0052, 0x0053,
645	/* 5x   5.25x   5.5x    5.75x */
646	0x0054, 0x0055, 0x0056, 0x0057,
647	/* 6x   6.25x   6.5x    6.75x */
648	0x0058, 0x0059, 0x005a, 0x005b,
649	/* 7x   7.25x   7.5x    7.75x */
650	0x005c, 0x005d, 0x005e, 0x005f,
651	/* 8x */
652	0x0060
653};
654
655/* Gain = .5 + bit[7:0] / 16 */
656static const u8 hv7131r_gain[] = {
657	0x08 /* 1x */, 0x0c /* 1.25x */, 0x10 /* 1.5x */, 0x14 /* 1.75x */,
658	0x18 /* 2x */, 0x1c /* 2.25x */, 0x20 /* 2.5x */, 0x24 /* 2.75x */,
659	0x28 /* 3x */, 0x2c /* 3.25x */, 0x30 /* 3.5x */, 0x34 /* 3.75x */,
660	0x38 /* 4x */, 0x3c /* 4.25x */, 0x40 /* 4.5x */, 0x44 /* 4.75x */,
661	0x48 /* 5x */, 0x4c /* 5.25x */, 0x50 /* 5.5x */, 0x54 /* 5.75x */,
662	0x58 /* 6x */, 0x5c /* 6.25x */, 0x60 /* 6.5x */, 0x64 /* 6.75x */,
663	0x68 /* 7x */, 0x6c /* 7.25x */, 0x70 /* 7.5x */, 0x74 /* 7.75x */,
664	0x78 /* 8x */
665};
666
667static const struct i2c_reg_u8 soi968_init[] = {
668	{0x0c, 0x00}, {0x0f, 0x1f},
669	{0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
670	{0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
671	{0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
672	{0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
673	{0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
674	{0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
675	{0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
676	{0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
677	{0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
678	{0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
679};
680
681static const struct i2c_reg_u8 ov7660_init[] = {
682	{0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
683	{0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
684	{0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
685	/* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
686	   0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
687	{0x17, 0x10}, {0x18, 0x61},
688	{0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
689	{0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0x00},
690	{0x2e, 0x00}, {0x01, 0x78}, {0x02, 0x50},
691};
692
693static const struct i2c_reg_u8 ov7670_init[] = {
694	{0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
695	{0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
696	{0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
697	{0xa2, 0x02}, {0x13, 0xe0}, {0x00, 0x00}, {0x10, 0x00},
698	{0x0d, 0x40}, {0x14, 0x28}, {0xa5, 0x05}, {0xab, 0x07},
699	{0x24, 0x95}, {0x25, 0x33}, {0x26, 0xe3}, {0x9f, 0x75},
700	{0xa0, 0x65}, {0xa1, 0x0b}, {0xa6, 0xd8}, {0xa7, 0xd8},
701	{0xa8, 0xf0}, {0xa9, 0x90}, {0xaa, 0x94}, {0x13, 0xe5},
702	{0x0e, 0x61}, {0x0f, 0x4b}, {0x16, 0x02}, {0x1e, 0x27},
703	{0x21, 0x02}, {0x22, 0x91}, {0x29, 0x07}, {0x33, 0x0b},
704	{0x35, 0x0b}, {0x37, 0x1d}, {0x38, 0x71}, {0x39, 0x2a},
705	{0x3c, 0x78}, {0x4d, 0x40}, {0x4e, 0x20}, {0x69, 0x00},
706	{0x74, 0x19}, {0x8d, 0x4f}, {0x8e, 0x00}, {0x8f, 0x00},
707	{0x90, 0x00}, {0x91, 0x00}, {0x96, 0x00}, {0x9a, 0x80},
708	{0xb0, 0x84}, {0xb1, 0x0c}, {0xb2, 0x0e}, {0xb3, 0x82},
709	{0xb8, 0x0a}, {0x43, 0x0a}, {0x44, 0xf0}, {0x45, 0x20},
710	{0x46, 0x7d}, {0x47, 0x29}, {0x48, 0x4a}, {0x59, 0x8c},
711	{0x5a, 0xa5}, {0x5b, 0xde}, {0x5c, 0x96}, {0x5d, 0x66},
712	{0x5e, 0x10}, {0x6c, 0x0a}, {0x6d, 0x55}, {0x6e, 0x11},
713	{0x6f, 0x9e}, {0x6a, 0x40}, {0x01, 0x40}, {0x02, 0x40},
714	{0x13, 0xe7}, {0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x02},
715	{0x52, 0x1d}, {0x53, 0x56}, {0x54, 0x73}, {0x55, 0x0a},
716	{0x56, 0x55}, {0x57, 0x80}, {0x58, 0x9e}, {0x41, 0x08},
717	{0x3f, 0x02}, {0x75, 0x03}, {0x76, 0x63}, {0x4c, 0x04},
718	{0x77, 0x06}, {0x3d, 0x02}, {0x4b, 0x09}, {0xc9, 0x30},
719	{0x41, 0x08}, {0x56, 0x48}, {0x34, 0x11}, {0xa4, 0x88},
720	{0x96, 0x00}, {0x97, 0x30}, {0x98, 0x20}, {0x99, 0x30},
721	{0x9a, 0x84}, {0x9b, 0x29}, {0x9c, 0x03}, {0x9d, 0x99},
722	{0x9e, 0x7f}, {0x78, 0x04}, {0x79, 0x01}, {0xc8, 0xf0},
723	{0x79, 0x0f}, {0xc8, 0x00}, {0x79, 0x10}, {0xc8, 0x7e},
724	{0x79, 0x0a}, {0xc8, 0x80}, {0x79, 0x0b}, {0xc8, 0x01},
725	{0x79, 0x0c}, {0xc8, 0x0f}, {0x79, 0x0d}, {0xc8, 0x20},
726	{0x79, 0x09}, {0xc8, 0x80}, {0x79, 0x02}, {0xc8, 0xc0},
727	{0x79, 0x03}, {0xc8, 0x40}, {0x79, 0x05}, {0xc8, 0x30},
728	{0x79, 0x26}, {0x62, 0x20}, {0x63, 0x00}, {0x64, 0x06},
729	{0x65, 0x00}, {0x66, 0x05}, {0x94, 0x05}, {0x95, 0x0a},
730	{0x17, 0x13}, {0x18, 0x01}, {0x19, 0x02}, {0x1a, 0x7a},
731	{0x46, 0x59}, {0x47, 0x30}, {0x58, 0x9a}, {0x59, 0x84},
732	{0x5a, 0x91}, {0x5b, 0x57}, {0x5c, 0x75}, {0x5d, 0x6d},
733	{0x5e, 0x13}, {0x64, 0x07}, {0x94, 0x07}, {0x95, 0x0d},
734	{0xa6, 0xdf}, {0xa7, 0xdf}, {0x48, 0x4d}, {0x51, 0x00},
735	{0x6b, 0x0a}, {0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00},
736	{0x92, 0x00}, {0x93, 0x00}, {0x55, 0x0a}, {0x56, 0x60},
737	{0x4f, 0x6e}, {0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d},
738	{0x53, 0x56}, {0x54, 0x73}, {0x58, 0x9a}, {0x4f, 0x6e},
739	{0x50, 0x70}, {0x51, 0x00}, {0x52, 0x1d}, {0x53, 0x56},
740	{0x54, 0x73}, {0x58, 0x9a}, {0x3f, 0x01}, {0x7b, 0x03},
741	{0x7c, 0x09}, {0x7d, 0x16}, {0x7e, 0x38}, {0x7f, 0x47},
742	{0x80, 0x53}, {0x81, 0x5e}, {0x82, 0x6a}, {0x83, 0x74},
743	{0x84, 0x80}, {0x85, 0x8c}, {0x86, 0x9b}, {0x87, 0xb2},
744	{0x88, 0xcc}, {0x89, 0xe5}, {0x7a, 0x24}, {0x3b, 0x00},
745	{0x9f, 0x76}, {0xa0, 0x65}, {0x13, 0xe2}, {0x6b, 0x0a},
746	{0x11, 0x80}, {0x2a, 0x00}, {0x2b, 0x00}, {0x92, 0x00},
747	{0x93, 0x00},
748};
749
750static const struct i2c_reg_u8 ov9650_init[] = {
751	{0x00, 0x00}, {0x01, 0x78},
752	{0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
753	{0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
754	{0x09, 0x01}, {0x0c, 0x00}, {0x0d, 0x00},
755	{0x0e, 0xa0}, {0x0f, 0x52}, {0x10, 0x7c},
756	{0x11, 0x80}, {0x12, 0x45}, {0x13, 0xc2},
757	{0x14, 0x2e}, {0x15, 0x00}, {0x16, 0x07},
758	{0x17, 0x24}, {0x18, 0xc5}, {0x19, 0x00},
759	{0x1a, 0x3c}, {0x1b, 0x00}, {0x1e, 0x04},
760	{0x1f, 0x00}, {0x24, 0x78}, {0x25, 0x68},
761	{0x26, 0xd4}, {0x27, 0x80}, {0x28, 0x80},
762	{0x29, 0x30}, {0x2a, 0x00}, {0x2b, 0x00},
763	{0x2c, 0x80}, {0x2d, 0x00}, {0x2e, 0x00},
764	{0x2f, 0x00}, {0x30, 0x08}, {0x31, 0x30},
765	{0x32, 0x84}, {0x33, 0xe2}, {0x34, 0xbf},
766	{0x35, 0x81}, {0x36, 0xf9}, {0x37, 0x00},
767	{0x38, 0x93}, {0x39, 0x50}, {0x3a, 0x01},
768	{0x3b, 0x01}, {0x3c, 0x73}, {0x3d, 0x19},
769	{0x3e, 0x0b}, {0x3f, 0x80}, {0x40, 0xc1},
770	{0x41, 0x00}, {0x42, 0x08}, {0x67, 0x80},
771	{0x68, 0x80}, {0x69, 0x40}, {0x6a, 0x00},
772	{0x6b, 0x0a}, {0x8b, 0x06}, {0x8c, 0x20},
773	{0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0xdf},
774	{0x92, 0x00}, {0x93, 0x00}, {0x94, 0x88},
775	{0x95, 0x88}, {0x96, 0x04}, {0xa1, 0x00},
776	{0xa5, 0x80}, {0xa8, 0x80}, {0xa9, 0xb8},
777	{0xaa, 0x92}, {0xab, 0x0a},
778};
779
780static const struct i2c_reg_u8 ov9655_init[] = {
781	{0x0e, 0x61}, {0x11, 0x80}, {0x13, 0xba},
782	{0x14, 0x2e}, {0x16, 0x24}, {0x1e, 0x04}, {0x27, 0x08},
783	{0x28, 0x08}, {0x29, 0x15}, {0x2c, 0x08}, {0x34, 0x3d},
784	{0x35, 0x00}, {0x38, 0x12}, {0x0f, 0x42}, {0x39, 0x57},
785	{0x3a, 0x00}, {0x3b, 0xcc}, {0x3c, 0x0c}, {0x3d, 0x19},
786	{0x3e, 0x0c}, {0x3f, 0x01}, {0x41, 0x40}, {0x42, 0x80},
787	{0x45, 0x46}, {0x46, 0x62}, {0x47, 0x2a}, {0x48, 0x3c},
788	{0x4a, 0xf0}, {0x4b, 0xdc}, {0x4c, 0xdc}, {0x4d, 0xdc},
789	{0x4e, 0xdc}, {0x6c, 0x04}, {0x6f, 0x9e}, {0x70, 0x05},
790	{0x71, 0x78}, {0x77, 0x02}, {0x8a, 0x23}, {0x90, 0x7e},
791	{0x91, 0x7c}, {0x9f, 0x6e}, {0xa0, 0x6e}, {0xa5, 0x68},
792	{0xa6, 0x60}, {0xa8, 0xc1}, {0xa9, 0xfa}, {0xaa, 0x92},
793	{0xab, 0x04}, {0xac, 0x80}, {0xad, 0x80}, {0xae, 0x80},
794	{0xaf, 0x80}, {0xb2, 0xf2}, {0xb3, 0x20}, {0xb5, 0x00},
795	{0xb6, 0xaf}, {0xbb, 0xae}, {0xbc, 0x44}, {0xbd, 0x44},
796	{0xbe, 0x3b}, {0xbf, 0x3a}, {0xc1, 0xc8}, {0xc2, 0x01},
797	{0xc4, 0x00}, {0xc6, 0x85}, {0xc7, 0x81}, {0xc9, 0xe0},
798	{0xca, 0xe8}, {0xcc, 0xd8}, {0xcd, 0x93}, {0x2d, 0x00},
799	{0x2e, 0x00}, {0x01, 0x80}, {0x02, 0x80}, {0x12, 0x61},
800	{0x36, 0xfa}, {0x8c, 0x8d}, {0xc0, 0xaa}, {0x69, 0x0a},
801	{0x03, 0x09}, {0x17, 0x16}, {0x18, 0x6e}, {0x19, 0x01},
802	{0x1a, 0x3e}, {0x32, 0x09}, {0x2a, 0x10}, {0x2b, 0x0a},
803	{0x92, 0x00}, {0x93, 0x00}, {0xa1, 0x00}, {0x10, 0x7c},
804	{0x04, 0x03}, {0x00, 0x13},
805};
806
807static const struct i2c_reg_u16 mt9v112_init[] = {
808	{0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
809	{0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
810	{0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
811	{0x05, 0x0000}, {0x06, 0x340c}, {0x3b, 0x042a},
812	{0x3c, 0x0400}, {0xf0, 0x0002}, {0x2e, 0x0c58},
813	{0x5b, 0x0001}, {0xc8, 0x9f0b}, {0xf0, 0x0001},
814	{0x9b, 0x5300}, {0xf0, 0x0000}, {0x2b, 0x0020},
815	{0x2c, 0x002a}, {0x2d, 0x0032}, {0x2e, 0x0020},
816	{0x09, 0x01dc}, {0x01, 0x000c}, {0x02, 0x0020},
817	{0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
818	{0x05, 0x0098}, {0x20, 0x0703}, {0x09, 0x01f2},
819	{0x2b, 0x00a0}, {0x2c, 0x00a0}, {0x2d, 0x00a0},
820	{0x2e, 0x00a0}, {0x01, 0x000c}, {0x02, 0x0020},
821	{0x03, 0x01e0}, {0x04, 0x0280}, {0x06, 0x000c},
822	{0x05, 0x0098}, {0x09, 0x01c1}, {0x2b, 0x00ae},
823	{0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
824};
825
826static const struct i2c_reg_u16 mt9v111_init[] = {
827	{0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
828	{0x01, 0x0001}, {0x05, 0x0004}, {0x2d, 0xe0a0},
829	{0x2e, 0x0c64},	{0x2f, 0x0064}, {0x06, 0x600e},
830	{0x08, 0x0480}, {0x01, 0x0004}, {0x02, 0x0016},
831	{0x03, 0x01e7}, {0x04, 0x0287}, {0x05, 0x0004},
832	{0x06, 0x002d},	{0x07, 0x3002}, {0x08, 0x0008},
833	{0x0e, 0x0008}, {0x20, 0x0000}
834};
835
836static const struct i2c_reg_u16 mt9v011_init[] = {
837	{0x07, 0x0002},	{0x0d, 0x0001},	{0x0d, 0x0000},
838	{0x01, 0x0008},	{0x02, 0x0016},	{0x03, 0x01e1},
839	{0x04, 0x0281},	{0x05, 0x0083},	{0x06, 0x0006},
840	{0x0d, 0x0002}, {0x0a, 0x0000},	{0x0b, 0x0000},
841	{0x0c, 0x0000},	{0x0d, 0x0000},	{0x0e, 0x0000},
842	{0x0f, 0x0000},	{0x10, 0x0000},	{0x11, 0x0000},
843	{0x12, 0x0000},	{0x13, 0x0000},	{0x14, 0x0000},
844	{0x15, 0x0000},	{0x16, 0x0000},	{0x17, 0x0000},
845	{0x18, 0x0000},	{0x19, 0x0000},	{0x1a, 0x0000},
846	{0x1b, 0x0000},	{0x1c, 0x0000},	{0x1d, 0x0000},
847	{0x32, 0x0000},	{0x20, 0x1101},	{0x21, 0x0000},
848	{0x22, 0x0000},	{0x23, 0x0000},	{0x24, 0x0000},
849	{0x25, 0x0000},	{0x26, 0x0000},	{0x27, 0x0024},
850	{0x2f, 0xf7b0},	{0x30, 0x0005},	{0x31, 0x0000},
851	{0x32, 0x0000},	{0x33, 0x0000},	{0x34, 0x0100},
852	{0x3d, 0x068f},	{0x40, 0x01e0},	{0x41, 0x00d1},
853	{0x44, 0x0082},	{0x5a, 0x0000},	{0x5b, 0x0000},
854	{0x5c, 0x0000},	{0x5d, 0x0000},	{0x5e, 0x0000},
855	{0x5f, 0xa31d},	{0x62, 0x0611},	{0x0a, 0x0000},
856	{0x06, 0x0029},	{0x05, 0x0009},	{0x20, 0x1101},
857	{0x20, 0x1101},	{0x09, 0x0064},	{0x07, 0x0003},
858	{0x2b, 0x0033},	{0x2c, 0x00a0},	{0x2d, 0x00a0},
859	{0x2e, 0x0033},	{0x07, 0x0002},	{0x06, 0x0000},
860	{0x06, 0x0029},	{0x05, 0x0009},
861};
862
863static const struct i2c_reg_u16 mt9m001_init[] = {
864	{0x0d, 0x0001},
865	{0x0d, 0x0000},
866	{0x04, 0x0500},		/* hres = 1280 */
867	{0x03, 0x0400},		/* vres = 1024 */
868	{0x20, 0x1100},
869	{0x06, 0x0010},
870	{0x2b, 0x0024},
871	{0x2e, 0x0024},
872	{0x35, 0x0024},
873	{0x2d, 0x0020},
874	{0x2c, 0x0020},
875	{0x09, 0x0ad4},
876	{0x35, 0x0057},
877};
878
879static const struct i2c_reg_u16 mt9m111_init[] = {
880	{0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
881	{0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
882	{0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
883	{0xf0, 0x0000},
884};
885
886static const struct i2c_reg_u16 mt9m112_init[] = {
887	{0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
888	{0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
889	{0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
890	{0xf0, 0x0000},
891};
892
893static const struct i2c_reg_u8 hv7131r_init[] = {
894	{0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
895	{0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
896	{0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
897	{0x01, 0x08}, {0x01, 0x08}, {0x25, 0x07},
898	{0x26, 0xc3}, {0x27, 0x50}, {0x30, 0x62},
899	{0x31, 0x10}, {0x32, 0x06}, {0x33, 0x10},
900	{0x20, 0x00}, {0x21, 0xd0}, {0x22, 0x00},
901	{0x23, 0x09}, {0x01, 0x08},
902};
903
904static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
905{
906	struct usb_device *dev = gspca_dev->dev;
907	int result;
908
909	if (gspca_dev->usb_err < 0)
910		return;
911	result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
912			0x00,
913			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
914			reg,
915			0x00,
916			gspca_dev->usb_buf,
917			length,
918			500);
919	if (unlikely(result < 0 || result != length)) {
920		pr_err("Read register %02x failed %d\n", reg, result);
921		gspca_dev->usb_err = result;
922		/*
923		 * Make sure the buffer is zeroed to avoid uninitialized
924		 * values.
925		 */
926		memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
927	}
928}
929
930static void reg_w(struct gspca_dev *gspca_dev, u16 reg,
931		 const u8 *buffer, int length)
932{
933	struct usb_device *dev = gspca_dev->dev;
934	int result;
935
936	if (gspca_dev->usb_err < 0)
937		return;
938	memcpy(gspca_dev->usb_buf, buffer, length);
939	result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
940			0x08,
941			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
942			reg,
943			0x00,
944			gspca_dev->usb_buf,
945			length,
946			500);
947	if (unlikely(result < 0 || result != length)) {
948		pr_err("Write register %02x failed %d\n", reg, result);
949		gspca_dev->usb_err = result;
950	}
951}
952
953static void reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
954{
955	reg_w(gspca_dev, reg, &value, 1);
956}
957
958static void i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
959{
960	int i;
961
962	reg_w(gspca_dev, 0x10c0, buffer, 8);
963	for (i = 0; i < 5; i++) {
964		reg_r(gspca_dev, 0x10c0, 1);
965		if (gspca_dev->usb_err < 0)
966			return;
967		if (gspca_dev->usb_buf[0] & 0x04) {
968			if (gspca_dev->usb_buf[0] & 0x08) {
969				pr_err("i2c_w error\n");
970				gspca_dev->usb_err = -EIO;
971			}
972			return;
973		}
974		msleep(10);
975	}
976	pr_err("i2c_w reg %02x no response\n", buffer[2]);
977/*	gspca_dev->usb_err = -EIO;	fixme: may occur */
978}
979
980static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
981{
982	struct sd *sd = (struct sd *) gspca_dev;
983	u8 row[8];
984
985	/*
986	 * from the point of view of the bridge, the length
987	 * includes the address
988	 */
989	row[0] = sd->i2c_intf | (2 << 4);
990	row[1] = sd->i2c_addr;
991	row[2] = reg;
992	row[3] = val;
993	row[4] = 0x00;
994	row[5] = 0x00;
995	row[6] = 0x00;
996	row[7] = 0x10;
997
998	i2c_w(gspca_dev, row);
999}
1000
1001static void i2c_w1_buf(struct gspca_dev *gspca_dev,
1002			const struct i2c_reg_u8 *buf, int sz)
1003{
1004	while (--sz >= 0) {
1005		i2c_w1(gspca_dev, buf->reg, buf->val);
1006		buf++;
1007	}
1008}
1009
1010static void i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
1011{
1012	struct sd *sd = (struct sd *) gspca_dev;
1013	u8 row[8];
1014
1015	/*
1016	 * from the point of view of the bridge, the length
1017	 * includes the address
1018	 */
1019	row[0] = sd->i2c_intf | (3 << 4);
1020	row[1] = sd->i2c_addr;
1021	row[2] = reg;
1022	row[3] = val >> 8;
1023	row[4] = val;
1024	row[5] = 0x00;
1025	row[6] = 0x00;
1026	row[7] = 0x10;
1027
1028	i2c_w(gspca_dev, row);
1029}
1030
1031static void i2c_w2_buf(struct gspca_dev *gspca_dev,
1032			const struct i2c_reg_u16 *buf, int sz)
1033{
1034	while (--sz >= 0) {
1035		i2c_w2(gspca_dev, buf->reg, buf->val);
1036		buf++;
1037	}
1038}
1039
1040static void i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
1041{
1042	struct sd *sd = (struct sd *) gspca_dev;
1043	u8 row[8];
1044
1045	row[0] = sd->i2c_intf | (1 << 4);
1046	row[1] = sd->i2c_addr;
1047	row[2] = reg;
1048	row[3] = 0;
1049	row[4] = 0;
1050	row[5] = 0;
1051	row[6] = 0;
1052	row[7] = 0x10;
1053	i2c_w(gspca_dev, row);
1054	row[0] = sd->i2c_intf | (1 << 4) | 0x02;
1055	row[2] = 0;
1056	i2c_w(gspca_dev, row);
1057	reg_r(gspca_dev, 0x10c2, 5);
1058	*val = gspca_dev->usb_buf[4];
1059}
1060
1061static void i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
1062{
1063	struct sd *sd = (struct sd *) gspca_dev;
1064	u8 row[8];
1065
1066	row[0] = sd->i2c_intf | (1 << 4);
1067	row[1] = sd->i2c_addr;
1068	row[2] = reg;
1069	row[3] = 0;
1070	row[4] = 0;
1071	row[5] = 0;
1072	row[6] = 0;
1073	row[7] = 0x10;
1074	i2c_w(gspca_dev, row);
1075	row[0] = sd->i2c_intf | (2 << 4) | 0x02;
1076	row[2] = 0;
1077	i2c_w(gspca_dev, row);
1078	reg_r(gspca_dev, 0x10c2, 5);
1079	*val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1080}
1081
1082static void ov9650_init_sensor(struct gspca_dev *gspca_dev)
1083{
1084	u16 id;
1085	struct sd *sd = (struct sd *) gspca_dev;
1086
1087	i2c_r2(gspca_dev, 0x1c, &id);
1088	if (gspca_dev->usb_err < 0)
1089		return;
1090
1091	if (id != 0x7fa2) {
1092		pr_err("sensor id for ov9650 doesn't match (0x%04x)\n", id);
1093		gspca_dev->usb_err = -ENODEV;
1094		return;
1095	}
1096
1097	i2c_w1(gspca_dev, 0x12, 0x80);		/* sensor reset */
1098	msleep(200);
1099	i2c_w1_buf(gspca_dev, ov9650_init, ARRAY_SIZE(ov9650_init));
1100	if (gspca_dev->usb_err < 0)
1101		pr_err("OV9650 sensor initialization failed\n");
1102	sd->hstart = 1;
1103	sd->vstart = 7;
1104}
1105
1106static void ov9655_init_sensor(struct gspca_dev *gspca_dev)
1107{
1108	struct sd *sd = (struct sd *) gspca_dev;
1109
1110	i2c_w1(gspca_dev, 0x12, 0x80);		/* sensor reset */
1111	msleep(200);
1112	i2c_w1_buf(gspca_dev, ov9655_init, ARRAY_SIZE(ov9655_init));
1113	if (gspca_dev->usb_err < 0)
1114		pr_err("OV9655 sensor initialization failed\n");
1115
1116	sd->hstart = 1;
1117	sd->vstart = 2;
1118}
1119
1120static void soi968_init_sensor(struct gspca_dev *gspca_dev)
1121{
1122	struct sd *sd = (struct sd *) gspca_dev;
1123
1124	i2c_w1(gspca_dev, 0x12, 0x80);		/* sensor reset */
1125	msleep(200);
1126	i2c_w1_buf(gspca_dev, soi968_init, ARRAY_SIZE(soi968_init));
1127	if (gspca_dev->usb_err < 0)
1128		pr_err("SOI968 sensor initialization failed\n");
1129
1130	sd->hstart = 60;
1131	sd->vstart = 11;
1132}
1133
1134static void ov7660_init_sensor(struct gspca_dev *gspca_dev)
1135{
1136	struct sd *sd = (struct sd *) gspca_dev;
1137
1138	i2c_w1(gspca_dev, 0x12, 0x80);		/* sensor reset */
1139	msleep(200);
1140	i2c_w1_buf(gspca_dev, ov7660_init, ARRAY_SIZE(ov7660_init));
1141	if (gspca_dev->usb_err < 0)
1142		pr_err("OV7660 sensor initialization failed\n");
1143	sd->hstart = 3;
1144	sd->vstart = 3;
1145}
1146
1147static void ov7670_init_sensor(struct gspca_dev *gspca_dev)
1148{
1149	struct sd *sd = (struct sd *) gspca_dev;
1150
1151	i2c_w1(gspca_dev, 0x12, 0x80);		/* sensor reset */
1152	msleep(200);
1153	i2c_w1_buf(gspca_dev, ov7670_init, ARRAY_SIZE(ov7670_init));
1154	if (gspca_dev->usb_err < 0)
1155		pr_err("OV7670 sensor initialization failed\n");
1156
1157	sd->hstart = 0;
1158	sd->vstart = 1;
1159}
1160
1161static void mt9v_init_sensor(struct gspca_dev *gspca_dev)
1162{
1163	struct sd *sd = (struct sd *) gspca_dev;
1164	u16 value;
1165
1166	sd->i2c_addr = 0x5d;
1167	i2c_r2(gspca_dev, 0xff, &value);
1168	if (gspca_dev->usb_err >= 0
1169	 && value == 0x8243) {
1170		i2c_w2_buf(gspca_dev, mt9v011_init, ARRAY_SIZE(mt9v011_init));
1171		if (gspca_dev->usb_err < 0) {
1172			pr_err("MT9V011 sensor initialization failed\n");
1173			return;
1174		}
1175		sd->hstart = 2;
1176		sd->vstart = 2;
1177		sd->sensor = SENSOR_MT9V011;
1178		pr_info("MT9V011 sensor detected\n");
1179		return;
1180	}
1181
1182	gspca_dev->usb_err = 0;
1183	sd->i2c_addr = 0x5c;
1184	i2c_w2(gspca_dev, 0x01, 0x0004);
1185	i2c_r2(gspca_dev, 0xff, &value);
1186	if (gspca_dev->usb_err >= 0
1187	 && value == 0x823a) {
1188		i2c_w2_buf(gspca_dev, mt9v111_init, ARRAY_SIZE(mt9v111_init));
1189		if (gspca_dev->usb_err < 0) {
1190			pr_err("MT9V111 sensor initialization failed\n");
1191			return;
1192		}
1193		sd->hstart = 2;
1194		sd->vstart = 2;
1195		sd->sensor = SENSOR_MT9V111;
1196		pr_info("MT9V111 sensor detected\n");
1197		return;
1198	}
1199
1200	gspca_dev->usb_err = 0;
1201	sd->i2c_addr = 0x5d;
1202	i2c_w2(gspca_dev, 0xf0, 0x0000);
1203	if (gspca_dev->usb_err < 0) {
1204		gspca_dev->usb_err = 0;
1205		sd->i2c_addr = 0x48;
1206		i2c_w2(gspca_dev, 0xf0, 0x0000);
1207	}
1208	i2c_r2(gspca_dev, 0x00, &value);
1209	if (gspca_dev->usb_err >= 0
1210	 && value == 0x1229) {
1211		i2c_w2_buf(gspca_dev, mt9v112_init, ARRAY_SIZE(mt9v112_init));
1212		if (gspca_dev->usb_err < 0) {
1213			pr_err("MT9V112 sensor initialization failed\n");
1214			return;
1215		}
1216		sd->hstart = 6;
1217		sd->vstart = 2;
1218		sd->sensor = SENSOR_MT9V112;
1219		pr_info("MT9V112 sensor detected\n");
1220		return;
1221	}
1222
1223	gspca_dev->usb_err = -ENODEV;
1224}
1225
1226static void mt9m112_init_sensor(struct gspca_dev *gspca_dev)
1227{
1228	struct sd *sd = (struct sd *) gspca_dev;
1229
1230	i2c_w2_buf(gspca_dev, mt9m112_init, ARRAY_SIZE(mt9m112_init));
1231	if (gspca_dev->usb_err < 0)
1232		pr_err("MT9M112 sensor initialization failed\n");
1233
1234	sd->hstart = 0;
1235	sd->vstart = 2;
1236}
1237
1238static void mt9m111_init_sensor(struct gspca_dev *gspca_dev)
1239{
1240	struct sd *sd = (struct sd *) gspca_dev;
1241
1242	i2c_w2_buf(gspca_dev, mt9m111_init, ARRAY_SIZE(mt9m111_init));
1243	if (gspca_dev->usb_err < 0)
1244		pr_err("MT9M111 sensor initialization failed\n");
1245
1246	sd->hstart = 0;
1247	sd->vstart = 2;
1248}
1249
1250static void mt9m001_init_sensor(struct gspca_dev *gspca_dev)
1251{
1252	struct sd *sd = (struct sd *) gspca_dev;
1253	u16 id;
1254
1255	i2c_r2(gspca_dev, 0x00, &id);
1256	if (gspca_dev->usb_err < 0)
1257		return;
1258
1259	/* must be 0x8411 or 0x8421 for colour sensor and 8431 for bw */
1260	switch (id) {
1261	case 0x8411:
1262	case 0x8421:
1263		pr_info("MT9M001 color sensor detected\n");
1264		break;
1265	case 0x8431:
1266		pr_info("MT9M001 mono sensor detected\n");
1267		break;
1268	default:
1269		pr_err("No MT9M001 chip detected, ID = %x\n\n", id);
1270		gspca_dev->usb_err = -ENODEV;
1271		return;
1272	}
1273
1274	i2c_w2_buf(gspca_dev, mt9m001_init, ARRAY_SIZE(mt9m001_init));
1275	if (gspca_dev->usb_err < 0)
1276		pr_err("MT9M001 sensor initialization failed\n");
1277
1278	sd->hstart = 1;
1279	sd->vstart = 1;
1280}
1281
1282static void hv7131r_init_sensor(struct gspca_dev *gspca_dev)
1283{
1284	struct sd *sd = (struct sd *) gspca_dev;
1285
1286	i2c_w1_buf(gspca_dev, hv7131r_init, ARRAY_SIZE(hv7131r_init));
1287	if (gspca_dev->usb_err < 0)
1288		pr_err("HV7131R Sensor initialization failed\n");
1289
1290	sd->hstart = 0;
1291	sd->vstart = 1;
1292}
1293
1294static void set_cmatrix(struct gspca_dev *gspca_dev,
1295		s32 brightness, s32 contrast, s32 satur, s32 hue)
1296{
1297	s32 hue_coord, hue_index = 180 + hue;
1298	u8 cmatrix[21];
1299
1300	memset(cmatrix, 0, sizeof(cmatrix));
1301	cmatrix[2] = (contrast * 0x25 / 0x100) + 0x26;
1302	cmatrix[0] = 0x13 + (cmatrix[2] - 0x26) * 0x13 / 0x25;
1303	cmatrix[4] = 0x07 + (cmatrix[2] - 0x26) * 0x07 / 0x25;
1304	cmatrix[18] = brightness - 0x80;
1305
1306	hue_coord = (hsv_red_x[hue_index] * satur) >> 8;
1307	cmatrix[6] = hue_coord;
1308	cmatrix[7] = (hue_coord >> 8) & 0x0f;
1309
1310	hue_coord = (hsv_red_y[hue_index] * satur) >> 8;
1311	cmatrix[8] = hue_coord;
1312	cmatrix[9] = (hue_coord >> 8) & 0x0f;
1313
1314	hue_coord = (hsv_green_x[hue_index] * satur) >> 8;
1315	cmatrix[10] = hue_coord;
1316	cmatrix[11] = (hue_coord >> 8) & 0x0f;
1317
1318	hue_coord = (hsv_green_y[hue_index] * satur) >> 8;
1319	cmatrix[12] = hue_coord;
1320	cmatrix[13] = (hue_coord >> 8) & 0x0f;
1321
1322	hue_coord = (hsv_blue_x[hue_index] * satur) >> 8;
1323	cmatrix[14] = hue_coord;
1324	cmatrix[15] = (hue_coord >> 8) & 0x0f;
1325
1326	hue_coord = (hsv_blue_y[hue_index] * satur) >> 8;
1327	cmatrix[16] = hue_coord;
1328	cmatrix[17] = (hue_coord >> 8) & 0x0f;
1329
1330	reg_w(gspca_dev, 0x10e1, cmatrix, 21);
1331}
1332
1333static void set_gamma(struct gspca_dev *gspca_dev, s32 val)
1334{
1335	u8 gamma[17];
1336	u8 gval = val * 0xb8 / 0x100;
1337
1338	gamma[0] = 0x0a;
1339	gamma[1] = 0x13 + (gval * (0xcb - 0x13) / 0xb8);
1340	gamma[2] = 0x25 + (gval * (0xee - 0x25) / 0xb8);
1341	gamma[3] = 0x37 + (gval * (0xfa - 0x37) / 0xb8);
1342	gamma[4] = 0x45 + (gval * (0xfc - 0x45) / 0xb8);
1343	gamma[5] = 0x55 + (gval * (0xfb - 0x55) / 0xb8);
1344	gamma[6] = 0x65 + (gval * (0xfc - 0x65) / 0xb8);
1345	gamma[7] = 0x74 + (gval * (0xfd - 0x74) / 0xb8);
1346	gamma[8] = 0x83 + (gval * (0xfe - 0x83) / 0xb8);
1347	gamma[9] = 0x92 + (gval * (0xfc - 0x92) / 0xb8);
1348	gamma[10] = 0xa1 + (gval * (0xfc - 0xa1) / 0xb8);
1349	gamma[11] = 0xb0 + (gval * (0xfc - 0xb0) / 0xb8);
1350	gamma[12] = 0xbf + (gval * (0xfb - 0xbf) / 0xb8);
1351	gamma[13] = 0xce + (gval * (0xfb - 0xce) / 0xb8);
1352	gamma[14] = 0xdf + (gval * (0xfd - 0xdf) / 0xb8);
1353	gamma[15] = 0xea + (gval * (0xf9 - 0xea) / 0xb8);
1354	gamma[16] = 0xf5;
1355
1356	reg_w(gspca_dev, 0x1190, gamma, 17);
1357}
1358
1359static void set_redblue(struct gspca_dev *gspca_dev, s32 blue, s32 red)
1360{
1361	reg_w1(gspca_dev, 0x118c, red);
1362	reg_w1(gspca_dev, 0x118f, blue);
1363}
1364
1365static void set_hvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
1366{
1367	u8 value, tslb;
1368	u16 value2;
1369	struct sd *sd = (struct sd *) gspca_dev;
1370
1371	if ((sd->flags & FLIP_DETECT) && dmi_check_system(flip_dmi_table)) {
1372		hflip = !hflip;
1373		vflip = !vflip;
1374	}
1375
1376	switch (sd->sensor) {
1377	case SENSOR_OV7660:
1378		value = 0x01;
1379		if (hflip)
1380			value |= 0x20;
1381		if (vflip) {
1382			value |= 0x10;
1383			sd->vstart = 2;
1384		} else {
1385			sd->vstart = 3;
1386		}
1387		reg_w1(gspca_dev, 0x1182, sd->vstart);
1388		i2c_w1(gspca_dev, 0x1e, value);
1389		break;
1390	case SENSOR_OV9650:
1391		i2c_r1(gspca_dev, 0x1e, &value);
1392		value &= ~0x30;
1393		tslb = 0x01;
1394		if (hflip)
1395			value |= 0x20;
1396		if (vflip) {
1397			value |= 0x10;
1398			tslb = 0x49;
1399		}
1400		i2c_w1(gspca_dev, 0x1e, value);
1401		i2c_w1(gspca_dev, 0x3a, tslb);
1402		break;
1403	case SENSOR_MT9V111:
1404	case SENSOR_MT9V011:
1405		i2c_r2(gspca_dev, 0x20, &value2);
1406		value2 &= ~0xc0a0;
1407		if (hflip)
1408			value2 |= 0x8080;
1409		if (vflip)
1410			value2 |= 0x4020;
1411		i2c_w2(gspca_dev, 0x20, value2);
1412		break;
1413	case SENSOR_MT9M112:
1414	case SENSOR_MT9M111:
1415	case SENSOR_MT9V112:
1416		i2c_r2(gspca_dev, 0x20, &value2);
1417		value2 &= ~0x0003;
1418		if (hflip)
1419			value2 |= 0x0002;
1420		if (vflip)
1421			value2 |= 0x0001;
1422		i2c_w2(gspca_dev, 0x20, value2);
1423		break;
1424	case SENSOR_HV7131R:
1425		i2c_r1(gspca_dev, 0x01, &value);
1426		value &= ~0x03;
1427		if (vflip)
1428			value |= 0x01;
1429		if (hflip)
1430			value |= 0x02;
1431		i2c_w1(gspca_dev, 0x01, value);
1432		break;
1433	}
1434}
1435
1436static void set_exposure(struct gspca_dev *gspca_dev, s32 expo)
1437{
1438	struct sd *sd = (struct sd *) gspca_dev;
1439	u8 exp[8] = {sd->i2c_intf, sd->i2c_addr,
1440				0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1441	int expo2;
1442
1443	if (gspca_dev->streaming)
1444		exp[7] = 0x1e;
1445
1446	switch (sd->sensor) {
1447	case SENSOR_OV7660:
1448	case SENSOR_OV7670:
1449	case SENSOR_OV9655:
1450	case SENSOR_OV9650:
1451		if (expo > 547)
1452			expo2 = 547;
1453		else
1454			expo2 = expo;
1455		exp[0] |= (2 << 4);
1456		exp[2] = 0x10;			/* AECH */
1457		exp[3] = expo2 >> 2;
1458		exp[7] = 0x10;
1459		i2c_w(gspca_dev, exp);
1460		exp[2] = 0x04;			/* COM1 */
1461		exp[3] = expo2 & 0x0003;
1462		exp[7] = 0x10;
1463		i2c_w(gspca_dev, exp);
1464		expo -= expo2;
1465		exp[7] = 0x1e;
1466		exp[0] |= (3 << 4);
1467		exp[2] = 0x2d;			/* ADVFL & ADVFH */
1468		exp[3] = expo;
1469		exp[4] = expo >> 8;
1470		break;
1471	case SENSOR_MT9M001:
1472	case SENSOR_MT9V112:
1473	case SENSOR_MT9V011:
1474		exp[0] |= (3 << 4);
1475		exp[2] = 0x09;
1476		exp[3] = expo >> 8;
1477		exp[4] = expo;
1478		break;
1479	case SENSOR_HV7131R:
1480		exp[0] |= (4 << 4);
1481		exp[2] = 0x25;
1482		exp[3] = expo >> 5;
1483		exp[4] = expo << 3;
1484		exp[5] = 0;
1485		break;
1486	default:
1487		return;
1488	}
1489	i2c_w(gspca_dev, exp);
1490}
1491
1492static void set_gain(struct gspca_dev *gspca_dev, s32 g)
1493{
1494	struct sd *sd = (struct sd *) gspca_dev;
1495	u8 gain[8] = {sd->i2c_intf, sd->i2c_addr,
1496				0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1497
1498	if (gspca_dev->streaming)
1499		gain[7] = 0x15;		/* or 1d ? */
1500
1501	switch (sd->sensor) {
1502	case SENSOR_OV7660:
1503	case SENSOR_OV7670:
1504	case SENSOR_SOI968:
1505	case SENSOR_OV9655:
1506	case SENSOR_OV9650:
1507		gain[0] |= (2 << 4);
1508		gain[3] = ov_gain[g];
1509		break;
1510	case SENSOR_MT9V011:
1511		gain[0] |= (3 << 4);
1512		gain[2] = 0x35;
1513		gain[3] = micron1_gain[g] >> 8;
1514		gain[4] = micron1_gain[g];
1515		break;
1516	case SENSOR_MT9V112:
1517		gain[0] |= (3 << 4);
1518		gain[2] = 0x2f;
1519		gain[3] = micron1_gain[g] >> 8;
1520		gain[4] = micron1_gain[g];
1521		break;
1522	case SENSOR_MT9M001:
1523		gain[0] |= (3 << 4);
1524		gain[2] = 0x2f;
1525		gain[3] = micron2_gain[g] >> 8;
1526		gain[4] = micron2_gain[g];
1527		break;
1528	case SENSOR_HV7131R:
1529		gain[0] |= (2 << 4);
1530		gain[2] = 0x30;
1531		gain[3] = hv7131r_gain[g];
1532		break;
1533	default:
1534		return;
1535	}
1536	i2c_w(gspca_dev, gain);
1537}
1538
1539static void set_led_mode(struct gspca_dev *gspca_dev, s32 val)
1540{
1541	reg_w1(gspca_dev, 0x1007, 0x60);
1542	reg_w1(gspca_dev, 0x1006, val ? 0x40 : 0x00);
1543}
1544
1545static void set_quality(struct gspca_dev *gspca_dev, s32 val)
1546{
1547	struct sd *sd = (struct sd *) gspca_dev;
1548
1549	jpeg_set_qual(sd->jpeg_hdr, val);
1550	reg_w1(gspca_dev, 0x1061, 0x01);	/* stop transfer */
1551	reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */
1552	reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
1553	reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
1554	reg_w1(gspca_dev, 0x1061, 0x03);	/* restart transfer */
1555	reg_w1(gspca_dev, 0x10e0, sd->fmt);
1556	sd->fmt ^= 0x0c;			/* invert QTAB use + write */
1557	reg_w1(gspca_dev, 0x10e0, sd->fmt);
1558}
1559
1560#ifdef CONFIG_VIDEO_ADV_DEBUG
1561static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1562			struct v4l2_dbg_register *reg)
1563{
1564	struct sd *sd = (struct sd *) gspca_dev;
1565
1566	reg->size = 1;
1567	switch (reg->match.addr) {
1568	case 0:
1569		if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1570			return -EINVAL;
1571		reg_r(gspca_dev, reg->reg, 1);
1572		reg->val = gspca_dev->usb_buf[0];
1573		return gspca_dev->usb_err;
1574	case 1:
1575		if (sd->sensor >= SENSOR_MT9V011 &&
1576		    sd->sensor <= SENSOR_MT9M112) {
1577			i2c_r2(gspca_dev, reg->reg, (u16 *) &reg->val);
1578			reg->size = 2;
1579		} else {
1580			i2c_r1(gspca_dev, reg->reg, (u8 *) &reg->val);
1581		}
1582		return gspca_dev->usb_err;
1583	}
1584	return -EINVAL;
1585}
1586
1587static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1588			const struct v4l2_dbg_register *reg)
1589{
1590	struct sd *sd = (struct sd *) gspca_dev;
1591
1592	switch (reg->match.addr) {
1593	case 0:
1594		if (reg->reg < 0x1000 || reg->reg > 0x11ff)
1595			return -EINVAL;
1596		reg_w1(gspca_dev, reg->reg, reg->val);
1597		return gspca_dev->usb_err;
1598	case 1:
1599		if (sd->sensor >= SENSOR_MT9V011 &&
1600		    sd->sensor <= SENSOR_MT9M112) {
1601			i2c_w2(gspca_dev, reg->reg, reg->val);
1602		} else {
1603			i2c_w1(gspca_dev, reg->reg, reg->val);
1604		}
1605		return gspca_dev->usb_err;
1606	}
1607	return -EINVAL;
1608}
1609
1610static int sd_chip_info(struct gspca_dev *gspca_dev,
1611			struct v4l2_dbg_chip_info *chip)
1612{
1613	if (chip->match.addr > 1)
1614		return -EINVAL;
1615	if (chip->match.addr == 1)
1616		strscpy(chip->name, "sensor", sizeof(chip->name));
1617	return 0;
1618}
1619#endif
1620
1621static int sd_config(struct gspca_dev *gspca_dev,
1622			const struct usb_device_id *id)
1623{
1624	struct sd *sd = (struct sd *) gspca_dev;
1625	struct cam *cam;
1626
1627	cam = &gspca_dev->cam;
1628	cam->needs_full_bandwidth = 1;
1629
1630	sd->sensor = id->driver_info >> 8;
1631	sd->i2c_addr = id->driver_info;
1632	sd->flags = id->driver_info >> 16;
1633	sd->i2c_intf = 0x80;			/* i2c 100 Kb/s */
1634
1635	switch (sd->sensor) {
1636	case SENSOR_MT9M112:
1637	case SENSOR_MT9M111:
1638	case SENSOR_OV9650:
1639	case SENSOR_SOI968:
1640		cam->cam_mode = sxga_mode;
1641		cam->nmodes = ARRAY_SIZE(sxga_mode);
1642		break;
1643	case SENSOR_MT9M001:
1644		cam->cam_mode = mono_mode;
1645		cam->nmodes = ARRAY_SIZE(mono_mode);
1646		break;
1647	case SENSOR_HV7131R:
1648		sd->i2c_intf = 0x81;			/* i2c 400 Kb/s */
1649		fallthrough;
1650	default:
1651		cam->cam_mode = vga_mode;
1652		cam->nmodes = ARRAY_SIZE(vga_mode);
1653		break;
1654	}
1655
1656	sd->old_step = 0;
1657	sd->older_step = 0;
1658	sd->exposure_step = 16;
1659
1660	INIT_WORK(&sd->work, qual_upd);
1661
1662	return 0;
1663}
1664
1665static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
1666{
1667	struct gspca_dev *gspca_dev =
1668		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
1669	struct sd *sd = (struct sd *)gspca_dev;
1670
1671	gspca_dev->usb_err = 0;
1672
1673	if (!gspca_dev->streaming)
1674		return 0;
1675
1676	switch (ctrl->id) {
1677	/* color control cluster */
1678	case V4L2_CID_BRIGHTNESS:
1679		set_cmatrix(gspca_dev, sd->brightness->val,
1680			sd->contrast->val, sd->saturation->val, sd->hue->val);
1681		break;
1682	case V4L2_CID_GAMMA:
1683		set_gamma(gspca_dev, ctrl->val);
1684		break;
1685	/* blue/red balance cluster */
1686	case V4L2_CID_BLUE_BALANCE:
1687		set_redblue(gspca_dev, sd->blue->val, sd->red->val);
1688		break;
1689	/* h/vflip cluster */
1690	case V4L2_CID_HFLIP:
1691		set_hvflip(gspca_dev, sd->hflip->val, sd->vflip->val);
1692		break;
1693	/* standalone exposure control */
1694	case V4L2_CID_EXPOSURE:
1695		set_exposure(gspca_dev, ctrl->val);
1696		break;
1697	/* standalone gain control */
1698	case V4L2_CID_GAIN:
1699		set_gain(gspca_dev, ctrl->val);
1700		break;
1701	/* autogain + exposure or gain control cluster */
1702	case V4L2_CID_AUTOGAIN:
1703		if (sd->sensor == SENSOR_SOI968)
1704			set_gain(gspca_dev, sd->gain->val);
1705		else
1706			set_exposure(gspca_dev, sd->exposure->val);
1707		break;
1708	case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1709		set_quality(gspca_dev, ctrl->val);
1710		break;
1711	case V4L2_CID_FLASH_LED_MODE:
1712		set_led_mode(gspca_dev, ctrl->val);
1713		break;
1714	}
1715	return gspca_dev->usb_err;
1716}
1717
1718static const struct v4l2_ctrl_ops sd_ctrl_ops = {
1719	.s_ctrl = sd_s_ctrl,
1720};
1721
1722static int sd_init_controls(struct gspca_dev *gspca_dev)
1723{
1724	struct sd *sd = (struct sd *) gspca_dev;
1725	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
1726
1727	gspca_dev->vdev.ctrl_handler = hdl;
1728	v4l2_ctrl_handler_init(hdl, 13);
1729
1730	sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1731			V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
1732	sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1733			V4L2_CID_CONTRAST, 0, 255, 1, 127);
1734	sd->saturation = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1735			V4L2_CID_SATURATION, 0, 255, 1, 127);
1736	sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1737			V4L2_CID_HUE, -180, 180, 1, 0);
1738
1739	sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1740			V4L2_CID_GAMMA, 0, 255, 1, 0x10);
1741
1742	sd->blue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1743			V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0x28);
1744	sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1745			V4L2_CID_RED_BALANCE, 0, 127, 1, 0x28);
1746
1747	if (sd->sensor != SENSOR_OV9655 && sd->sensor != SENSOR_SOI968 &&
1748	    sd->sensor != SENSOR_OV7670 && sd->sensor != SENSOR_MT9M001 &&
1749	    sd->sensor != SENSOR_MT9VPRB) {
1750		sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1751			V4L2_CID_HFLIP, 0, 1, 1, 0);
1752		sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1753			V4L2_CID_VFLIP, 0, 1, 1, 0);
1754	}
1755
1756	if (sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_MT9VPRB &&
1757	    sd->sensor != SENSOR_MT9M112 && sd->sensor != SENSOR_MT9M111 &&
1758	    sd->sensor != SENSOR_MT9V111)
1759		sd->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1760			V4L2_CID_EXPOSURE, 0, 0x1780, 1, 0x33);
1761
1762	if (sd->sensor != SENSOR_MT9VPRB && sd->sensor != SENSOR_MT9M112 &&
1763	    sd->sensor != SENSOR_MT9M111 && sd->sensor != SENSOR_MT9V111) {
1764		sd->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1765			V4L2_CID_GAIN, 0, 28, 1, 0);
1766		sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1767			V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1768	}
1769
1770	sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
1771			V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80);
1772
1773	if (sd->flags & HAS_LED_TORCH)
1774		sd->led_mode = v4l2_ctrl_new_std_menu(hdl, &sd_ctrl_ops,
1775				V4L2_CID_FLASH_LED_MODE, V4L2_FLASH_LED_MODE_TORCH,
1776				~0x5, V4L2_FLASH_LED_MODE_NONE);
1777
1778	if (hdl->error) {
1779		pr_err("Could not initialize controls\n");
1780		return hdl->error;
1781	}
1782
1783	v4l2_ctrl_cluster(4, &sd->brightness);
1784	v4l2_ctrl_cluster(2, &sd->blue);
1785	if (sd->hflip)
1786		v4l2_ctrl_cluster(2, &sd->hflip);
1787	if (sd->autogain) {
1788		if (sd->sensor == SENSOR_SOI968)
1789			/* this sensor doesn't have the exposure control and
1790			   autogain is clustered with gain instead. This works
1791			   because sd->exposure == NULL. */
1792			v4l2_ctrl_auto_cluster(3, &sd->autogain, 0, false);
1793		else
1794			/* Otherwise autogain is clustered with exposure. */
1795			v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false);
1796	}
1797	return 0;
1798}
1799
1800static int sd_init(struct gspca_dev *gspca_dev)
1801{
1802	struct sd *sd = (struct sd *) gspca_dev;
1803	int i;
1804	u8 value;
1805	u8 i2c_init[9] = {
1806		0x80, sd->i2c_addr, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
1807	};
1808
1809	for (i = 0; i < ARRAY_SIZE(bridge_init); i++) {
1810		value = bridge_init[i][1];
1811		reg_w(gspca_dev, bridge_init[i][0], &value, 1);
1812		if (gspca_dev->usb_err < 0) {
1813			pr_err("Device initialization failed\n");
1814			return gspca_dev->usb_err;
1815		}
1816	}
1817
1818	if (sd->flags & LED_REVERSE)
1819		reg_w1(gspca_dev, 0x1006, 0x00);
1820	else
1821		reg_w1(gspca_dev, 0x1006, 0x20);
1822
1823	reg_w(gspca_dev, 0x10c0, i2c_init, 9);
1824	if (gspca_dev->usb_err < 0) {
1825		pr_err("Device initialization failed\n");
1826		return gspca_dev->usb_err;
1827	}
1828
1829	switch (sd->sensor) {
1830	case SENSOR_OV9650:
1831		ov9650_init_sensor(gspca_dev);
1832		if (gspca_dev->usb_err < 0)
1833			break;
1834		pr_info("OV9650 sensor detected\n");
1835		break;
1836	case SENSOR_OV9655:
1837		ov9655_init_sensor(gspca_dev);
1838		if (gspca_dev->usb_err < 0)
1839			break;
1840		pr_info("OV9655 sensor detected\n");
1841		break;
1842	case SENSOR_SOI968:
1843		soi968_init_sensor(gspca_dev);
1844		if (gspca_dev->usb_err < 0)
1845			break;
1846		pr_info("SOI968 sensor detected\n");
1847		break;
1848	case SENSOR_OV7660:
1849		ov7660_init_sensor(gspca_dev);
1850		if (gspca_dev->usb_err < 0)
1851			break;
1852		pr_info("OV7660 sensor detected\n");
1853		break;
1854	case SENSOR_OV7670:
1855		ov7670_init_sensor(gspca_dev);
1856		if (gspca_dev->usb_err < 0)
1857			break;
1858		pr_info("OV7670 sensor detected\n");
1859		break;
1860	case SENSOR_MT9VPRB:
1861		mt9v_init_sensor(gspca_dev);
1862		if (gspca_dev->usb_err < 0)
1863			break;
1864		pr_info("MT9VPRB sensor detected\n");
1865		break;
1866	case SENSOR_MT9M111:
1867		mt9m111_init_sensor(gspca_dev);
1868		if (gspca_dev->usb_err < 0)
1869			break;
1870		pr_info("MT9M111 sensor detected\n");
1871		break;
1872	case SENSOR_MT9M112:
1873		mt9m112_init_sensor(gspca_dev);
1874		if (gspca_dev->usb_err < 0)
1875			break;
1876		pr_info("MT9M112 sensor detected\n");
1877		break;
1878	case SENSOR_MT9M001:
1879		mt9m001_init_sensor(gspca_dev);
1880		if (gspca_dev->usb_err < 0)
1881			break;
1882		break;
1883	case SENSOR_HV7131R:
1884		hv7131r_init_sensor(gspca_dev);
1885		if (gspca_dev->usb_err < 0)
1886			break;
1887		pr_info("HV7131R sensor detected\n");
1888		break;
1889	default:
1890		pr_err("Unsupported sensor\n");
1891		gspca_dev->usb_err = -ENODEV;
1892	}
1893	return gspca_dev->usb_err;
1894}
1895
1896static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
1897{
1898	struct sd *sd = (struct sd *) gspca_dev;
1899	u8 value;
1900
1901	switch (sd->sensor) {
1902	case SENSOR_SOI968:
1903		if (mode & MODE_SXGA) {
1904			i2c_w1(gspca_dev, 0x17, 0x1d);
1905			i2c_w1(gspca_dev, 0x18, 0xbd);
1906			i2c_w1(gspca_dev, 0x19, 0x01);
1907			i2c_w1(gspca_dev, 0x1a, 0x81);
1908			i2c_w1(gspca_dev, 0x12, 0x00);
1909			sd->hstart = 140;
1910			sd->vstart = 19;
1911		} else {
1912			i2c_w1(gspca_dev, 0x17, 0x13);
1913			i2c_w1(gspca_dev, 0x18, 0x63);
1914			i2c_w1(gspca_dev, 0x19, 0x01);
1915			i2c_w1(gspca_dev, 0x1a, 0x79);
1916			i2c_w1(gspca_dev, 0x12, 0x40);
1917			sd->hstart = 60;
1918			sd->vstart = 11;
1919		}
1920		break;
1921	case SENSOR_OV9650:
1922		if (mode & MODE_SXGA) {
1923			i2c_w1(gspca_dev, 0x17, 0x1b);
1924			i2c_w1(gspca_dev, 0x18, 0xbc);
1925			i2c_w1(gspca_dev, 0x19, 0x01);
1926			i2c_w1(gspca_dev, 0x1a, 0x82);
1927			i2c_r1(gspca_dev, 0x12, &value);
1928			i2c_w1(gspca_dev, 0x12, value & 0x07);
1929		} else {
1930			i2c_w1(gspca_dev, 0x17, 0x24);
1931			i2c_w1(gspca_dev, 0x18, 0xc5);
1932			i2c_w1(gspca_dev, 0x19, 0x00);
1933			i2c_w1(gspca_dev, 0x1a, 0x3c);
1934			i2c_r1(gspca_dev, 0x12, &value);
1935			i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
1936		}
1937		break;
1938	case SENSOR_MT9M112:
1939	case SENSOR_MT9M111:
1940		if (mode & MODE_SXGA) {
1941			i2c_w2(gspca_dev, 0xf0, 0x0002);
1942			i2c_w2(gspca_dev, 0xc8, 0x970b);
1943			i2c_w2(gspca_dev, 0xf0, 0x0000);
1944		} else {
1945			i2c_w2(gspca_dev, 0xf0, 0x0002);
1946			i2c_w2(gspca_dev, 0xc8, 0x8000);
1947			i2c_w2(gspca_dev, 0xf0, 0x0000);
1948		}
1949		break;
1950	}
1951}
1952
1953static int sd_isoc_init(struct gspca_dev *gspca_dev)
1954{
1955	struct usb_interface *intf;
1956	u32 flags = gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv;
1957
1958	/*
1959	 * When using the SN9C20X_I420 fmt the sn9c20x needs more bandwidth
1960	 * than our regular bandwidth calculations reserve, so we force the
1961	 * use of a specific altsetting when using the SN9C20X_I420 fmt.
1962	 */
1963	if (!(flags & (MODE_RAW | MODE_JPEG))) {
1964		intf = usb_ifnum_to_if(gspca_dev->dev, gspca_dev->iface);
1965
1966		if (intf->num_altsetting != 9) {
1967			pr_warn("sn9c20x camera with unknown number of alt settings (%d), please report!\n",
1968				intf->num_altsetting);
1969			gspca_dev->alt = intf->num_altsetting;
1970			return 0;
1971		}
1972
1973		switch (gspca_dev->pixfmt.width) {
1974		case 160: /* 160x120 */
1975			gspca_dev->alt = 2;
1976			break;
1977		case 320: /* 320x240 */
1978			gspca_dev->alt = 6;
1979			break;
1980		default:  /* >= 640x480 */
1981			gspca_dev->alt = 9;
1982			break;
1983		}
1984	}
1985
1986	return 0;
1987}
1988
1989#define HW_WIN(mode, hstart, vstart) \
1990((const u8 []){hstart, 0, vstart, 0, \
1991(mode & MODE_SXGA ? 1280 >> 4 : 640 >> 4), \
1992(mode & MODE_SXGA ? 1024 >> 3 : 480 >> 3)})
1993
1994#define CLR_WIN(width, height) \
1995((const u8 [])\
1996{0, width >> 2, 0, height >> 1,\
1997((width >> 10) & 0x01) | ((height >> 8) & 0x6)})
1998
1999static int sd_start(struct gspca_dev *gspca_dev)
2000{
2001	struct sd *sd = (struct sd *) gspca_dev;
2002	int mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
2003	int width = gspca_dev->pixfmt.width;
2004	int height = gspca_dev->pixfmt.height;
2005	u8 fmt, scale = 0;
2006
2007	jpeg_define(sd->jpeg_hdr, height, width,
2008			0x21);
2009	jpeg_set_qual(sd->jpeg_hdr, v4l2_ctrl_g_ctrl(sd->jpegqual));
2010
2011	if (mode & MODE_RAW)
2012		fmt = 0x2d;
2013	else if (mode & MODE_JPEG)
2014		fmt = 0x24;
2015	else
2016		fmt = 0x2f;	/* YUV 420 */
2017	sd->fmt = fmt;
2018
2019	switch (mode & SCALE_MASK) {
2020	case SCALE_1280x1024:
2021		scale = 0xc0;
2022		pr_info("Set 1280x1024\n");
2023		break;
2024	case SCALE_640x480:
2025		scale = 0x80;
2026		pr_info("Set 640x480\n");
2027		break;
2028	case SCALE_320x240:
2029		scale = 0x90;
2030		pr_info("Set 320x240\n");
2031		break;
2032	case SCALE_160x120:
2033		scale = 0xa0;
2034		pr_info("Set 160x120\n");
2035		break;
2036	}
2037
2038	configure_sensor_output(gspca_dev, mode);
2039	reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2040	reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2041	reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
2042	reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
2043	reg_w1(gspca_dev, 0x1189, scale);
2044	reg_w1(gspca_dev, 0x10e0, fmt);
2045
2046	set_cmatrix(gspca_dev, v4l2_ctrl_g_ctrl(sd->brightness),
2047			v4l2_ctrl_g_ctrl(sd->contrast),
2048			v4l2_ctrl_g_ctrl(sd->saturation),
2049			v4l2_ctrl_g_ctrl(sd->hue));
2050	set_gamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma));
2051	set_redblue(gspca_dev, v4l2_ctrl_g_ctrl(sd->blue),
2052			v4l2_ctrl_g_ctrl(sd->red));
2053	if (sd->gain)
2054		set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain));
2055	if (sd->exposure)
2056		set_exposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure));
2057	if (sd->hflip)
2058		set_hvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip),
2059				v4l2_ctrl_g_ctrl(sd->vflip));
2060
2061	reg_w1(gspca_dev, 0x1007, 0x20);
2062	reg_w1(gspca_dev, 0x1061, 0x03);
2063
2064	/* if JPEG, prepare the compression quality update */
2065	if (mode & MODE_JPEG) {
2066		sd->pktsz = sd->npkt = 0;
2067		sd->nchg = 0;
2068	}
2069	if (sd->led_mode)
2070		v4l2_ctrl_s_ctrl(sd->led_mode, 0);
2071
2072	return gspca_dev->usb_err;
2073}
2074
2075static void sd_stopN(struct gspca_dev *gspca_dev)
2076{
2077	reg_w1(gspca_dev, 0x1007, 0x00);
2078	reg_w1(gspca_dev, 0x1061, 0x01);
2079}
2080
2081/* called on streamoff with alt==0 and on disconnect */
2082/* the usb_lock is held at entry - restore on exit */
2083static void sd_stop0(struct gspca_dev *gspca_dev)
2084{
2085	struct sd *sd = (struct sd *) gspca_dev;
2086
2087	mutex_unlock(&gspca_dev->usb_lock);
2088	flush_work(&sd->work);
2089	mutex_lock(&gspca_dev->usb_lock);
2090}
2091
2092static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
2093{
2094	struct sd *sd = (struct sd *) gspca_dev;
2095	s32 cur_exp = v4l2_ctrl_g_ctrl(sd->exposure);
2096	s32 max = sd->exposure->maximum - sd->exposure_step;
2097	s32 min = sd->exposure->minimum + sd->exposure_step;
2098	s16 new_exp;
2099
2100	/*
2101	 * some hardcoded values are present
2102	 * like those for maximal/minimal exposure
2103	 * and exposure steps
2104	 */
2105	if (avg_lum < MIN_AVG_LUM) {
2106		if (cur_exp > max)
2107			return;
2108
2109		new_exp = cur_exp + sd->exposure_step;
2110		if (new_exp > max)
2111			new_exp = max;
2112		if (new_exp < min)
2113			new_exp = min;
2114		v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2115
2116		sd->older_step = sd->old_step;
2117		sd->old_step = 1;
2118
2119		if (sd->old_step ^ sd->older_step)
2120			sd->exposure_step /= 2;
2121		else
2122			sd->exposure_step += 2;
2123	}
2124	if (avg_lum > MAX_AVG_LUM) {
2125		if (cur_exp < min)
2126			return;
2127		new_exp = cur_exp - sd->exposure_step;
2128		if (new_exp > max)
2129			new_exp = max;
2130		if (new_exp < min)
2131			new_exp = min;
2132		v4l2_ctrl_s_ctrl(sd->exposure, new_exp);
2133		sd->older_step = sd->old_step;
2134		sd->old_step = 0;
2135
2136		if (sd->old_step ^ sd->older_step)
2137			sd->exposure_step /= 2;
2138		else
2139			sd->exposure_step += 2;
2140	}
2141}
2142
2143static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
2144{
2145	struct sd *sd = (struct sd *) gspca_dev;
2146	s32 cur_gain = v4l2_ctrl_g_ctrl(sd->gain);
2147
2148	if (avg_lum < MIN_AVG_LUM && cur_gain < sd->gain->maximum)
2149		v4l2_ctrl_s_ctrl(sd->gain, cur_gain + 1);
2150	if (avg_lum > MAX_AVG_LUM && cur_gain > sd->gain->minimum)
2151		v4l2_ctrl_s_ctrl(sd->gain, cur_gain - 1);
2152}
2153
2154static void sd_dqcallback(struct gspca_dev *gspca_dev)
2155{
2156	struct sd *sd = (struct sd *) gspca_dev;
2157	int avg_lum;
2158
2159	if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain))
2160		return;
2161
2162	avg_lum = atomic_read(&sd->avg_lum);
2163	if (sd->sensor == SENSOR_SOI968)
2164		do_autogain(gspca_dev, avg_lum);
2165	else
2166		do_autoexposure(gspca_dev, avg_lum);
2167}
2168
2169/* JPEG quality update */
2170/* This function is executed from a work queue. */
2171static void qual_upd(struct work_struct *work)
2172{
2173	struct sd *sd = container_of(work, struct sd, work);
2174	struct gspca_dev *gspca_dev = &sd->gspca_dev;
2175	s32 qual = v4l2_ctrl_g_ctrl(sd->jpegqual);
2176
2177	/* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
2178	mutex_lock(&gspca_dev->usb_lock);
2179	gspca_dbg(gspca_dev, D_STREAM, "qual_upd %d%%\n", qual);
2180	gspca_dev->usb_err = 0;
2181	set_quality(gspca_dev, qual);
2182	mutex_unlock(&gspca_dev->usb_lock);
2183}
2184
2185#if IS_ENABLED(CONFIG_INPUT)
2186static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2187			u8 *data,		/* interrupt packet */
2188			int len)		/* interrupt packet length */
2189{
2190	struct sd *sd = (struct sd *) gspca_dev;
2191
2192	if (!(sd->flags & HAS_NO_BUTTON) && len == 1) {
2193		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2194		input_sync(gspca_dev->input_dev);
2195		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2196		input_sync(gspca_dev->input_dev);
2197		return 0;
2198	}
2199	return -EINVAL;
2200}
2201#endif
2202
2203/* check the JPEG compression */
2204static void transfer_check(struct gspca_dev *gspca_dev,
2205			u8 *data)
2206{
2207	struct sd *sd = (struct sd *) gspca_dev;
2208	int new_qual, r;
2209
2210	new_qual = 0;
2211
2212	/* if USB error, discard the frame and decrease the quality */
2213	if (data[6] & 0x08) {				/* USB FIFO full */
2214		gspca_dev->last_packet_type = DISCARD_PACKET;
2215		new_qual = -5;
2216	} else {
2217
2218		/* else, compute the filling rate and a new JPEG quality */
2219		r = (sd->pktsz * 100) /
2220			(sd->npkt *
2221				gspca_dev->urb[0]->iso_frame_desc[0].length);
2222		if (r >= 85)
2223			new_qual = -3;
2224		else if (r < 75)
2225			new_qual = 2;
2226	}
2227	if (new_qual != 0) {
2228		sd->nchg += new_qual;
2229		if (sd->nchg < -6 || sd->nchg >= 12) {
2230			/* Note: we are in interrupt context, so we can't
2231			   use v4l2_ctrl_g/s_ctrl here. Access the value
2232			   directly instead. */
2233			s32 curqual = sd->jpegqual->cur.val;
2234			sd->nchg = 0;
2235			new_qual += curqual;
2236			if (new_qual < sd->jpegqual->minimum)
2237				new_qual = sd->jpegqual->minimum;
2238			else if (new_qual > sd->jpegqual->maximum)
2239				new_qual = sd->jpegqual->maximum;
2240			if (new_qual != curqual) {
2241				sd->jpegqual->cur.val = new_qual;
2242				schedule_work(&sd->work);
2243			}
2244		}
2245	} else {
2246		sd->nchg = 0;
2247	}
2248	sd->pktsz = sd->npkt = 0;
2249}
2250
2251static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2252			u8 *data,			/* isoc packet */
2253			int len)			/* iso packet length */
2254{
2255	struct sd *sd = (struct sd *) gspca_dev;
2256	int avg_lum, is_jpeg;
2257	static const u8 frame_header[] = {
2258		0xff, 0xff, 0x00, 0xc4, 0xc4, 0x96
2259	};
2260
2261	is_jpeg = (sd->fmt & 0x03) == 0;
2262	if (len >= 64 && memcmp(data, frame_header, 6) == 0) {
2263		avg_lum = ((data[35] >> 2) & 3) |
2264			   (data[20] << 2) |
2265			   (data[19] << 10);
2266		avg_lum += ((data[35] >> 4) & 3) |
2267			    (data[22] << 2) |
2268			    (data[21] << 10);
2269		avg_lum += ((data[35] >> 6) & 3) |
2270			    (data[24] << 2) |
2271			    (data[23] << 10);
2272		avg_lum += (data[36] & 3) |
2273			   (data[26] << 2) |
2274			   (data[25] << 10);
2275		avg_lum += ((data[36] >> 2) & 3) |
2276			    (data[28] << 2) |
2277			    (data[27] << 10);
2278		avg_lum += ((data[36] >> 4) & 3) |
2279			    (data[30] << 2) |
2280			    (data[29] << 10);
2281		avg_lum += ((data[36] >> 6) & 3) |
2282			    (data[32] << 2) |
2283			    (data[31] << 10);
2284		avg_lum += ((data[44] >> 4) & 3) |
2285			    (data[34] << 2) |
2286			    (data[33] << 10);
2287		avg_lum >>= 9;
2288		atomic_set(&sd->avg_lum, avg_lum);
2289
2290		if (is_jpeg)
2291			transfer_check(gspca_dev, data);
2292
2293		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2294		len -= 64;
2295		if (len == 0)
2296			return;
2297		data += 64;
2298	}
2299	if (gspca_dev->last_packet_type == LAST_PACKET) {
2300		if (is_jpeg) {
2301			gspca_frame_add(gspca_dev, FIRST_PACKET,
2302				sd->jpeg_hdr, JPEG_HDR_SZ);
2303			gspca_frame_add(gspca_dev, INTER_PACKET,
2304				data, len);
2305		} else {
2306			gspca_frame_add(gspca_dev, FIRST_PACKET,
2307				data, len);
2308		}
2309	} else {
2310		/* if JPEG, count the packets and their size */
2311		if (is_jpeg) {
2312			sd->npkt++;
2313			sd->pktsz += len;
2314		}
2315		gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2316	}
2317}
2318
2319/* sub-driver description */
2320static const struct sd_desc sd_desc = {
2321	.name = KBUILD_MODNAME,
2322	.config = sd_config,
2323	.init = sd_init,
2324	.init_controls = sd_init_controls,
2325	.isoc_init = sd_isoc_init,
2326	.start = sd_start,
2327	.stopN = sd_stopN,
2328	.stop0 = sd_stop0,
2329	.pkt_scan = sd_pkt_scan,
2330#if IS_ENABLED(CONFIG_INPUT)
2331	.int_pkt_scan = sd_int_pkt_scan,
2332#endif
2333	.dq_callback = sd_dqcallback,
2334#ifdef CONFIG_VIDEO_ADV_DEBUG
2335	.set_register = sd_dbg_s_register,
2336	.get_register = sd_dbg_g_register,
2337	.get_chip_info = sd_chip_info,
2338#endif
2339};
2340
2341#define SN9C20X(sensor, i2c_addr, flags) \
2342	.driver_info =  ((flags & 0xff) << 16) \
2343			| (SENSOR_ ## sensor << 8) \
2344			| (i2c_addr)
2345
2346static const struct usb_device_id device_table[] = {
2347	{USB_DEVICE(0x0c45, 0x6240), SN9C20X(MT9M001, 0x5d, 0)},
2348	{USB_DEVICE(0x0c45, 0x6242), SN9C20X(MT9M111, 0x5d, HAS_LED_TORCH)},
2349	{USB_DEVICE(0x0c45, 0x6248), SN9C20X(OV9655, 0x30, 0)},
2350	{USB_DEVICE(0x0c45, 0x624c), SN9C20X(MT9M112, 0x5d, 0)},
2351	{USB_DEVICE(0x0c45, 0x624e), SN9C20X(SOI968, 0x30, LED_REVERSE)},
2352	{USB_DEVICE(0x0c45, 0x624f), SN9C20X(OV9650, 0x30,
2353					     (FLIP_DETECT | HAS_NO_BUTTON))},
2354	{USB_DEVICE(0x0c45, 0x6251), SN9C20X(OV9650, 0x30, 0)},
2355	{USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2356	{USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2357	{USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2358	{USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)},
2359	{USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2360	{USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2361	{USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
2362	{USB_DEVICE(0x0c45, 0x6282), SN9C20X(MT9M111, 0x5d, 0)},
2363	{USB_DEVICE(0x0c45, 0x6288), SN9C20X(OV9655, 0x30, 0)},
2364	{USB_DEVICE(0x0c45, 0x628c), SN9C20X(MT9M112, 0x5d, 0)},
2365	{USB_DEVICE(0x0c45, 0x628e), SN9C20X(SOI968, 0x30, 0)},
2366	{USB_DEVICE(0x0c45, 0x628f), SN9C20X(OV9650, 0x30, 0)},
2367	{USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2368	{USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2369	{USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, LED_REVERSE)},
2370	{USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)},
2371	{USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2372	{USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2373	{USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
2374	{USB_DEVICE(0x0458, 0x7029), SN9C20X(HV7131R, 0x11, 0)},
2375	{USB_DEVICE(0x0458, 0x7045), SN9C20X(MT9M112, 0x5d, LED_REVERSE)},
2376	{USB_DEVICE(0x0458, 0x704a), SN9C20X(MT9M112, 0x5d, 0)},
2377	{USB_DEVICE(0x0458, 0x704c), SN9C20X(MT9M112, 0x5d, 0)},
2378	{USB_DEVICE(0xa168, 0x0610), SN9C20X(HV7131R, 0x11, 0)},
2379	{USB_DEVICE(0xa168, 0x0611), SN9C20X(HV7131R, 0x11, 0)},
2380	{USB_DEVICE(0xa168, 0x0613), SN9C20X(HV7131R, 0x11, 0)},
2381	{USB_DEVICE(0xa168, 0x0618), SN9C20X(HV7131R, 0x11, 0)},
2382	{USB_DEVICE(0xa168, 0x0614), SN9C20X(MT9M111, 0x5d, 0)},
2383	{USB_DEVICE(0xa168, 0x0615), SN9C20X(MT9M111, 0x5d, 0)},
2384	{USB_DEVICE(0xa168, 0x0617), SN9C20X(MT9M111, 0x5d, 0)},
2385	{}
2386};
2387MODULE_DEVICE_TABLE(usb, device_table);
2388
2389/* -- device connect -- */
2390static int sd_probe(struct usb_interface *intf,
2391		    const struct usb_device_id *id)
2392{
2393	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2394				THIS_MODULE);
2395}
2396
2397static struct usb_driver sd_driver = {
2398	.name = KBUILD_MODNAME,
2399	.id_table = device_table,
2400	.probe = sd_probe,
2401	.disconnect = gspca_disconnect,
2402#ifdef CONFIG_PM
2403	.suspend = gspca_suspend,
2404	.resume = gspca_resume,
2405	.reset_resume = gspca_resume,
2406#endif
2407};
2408
2409module_usb_driver(sd_driver);
2410