1 /*
2  * T613 subdriver
3  *
4  * Copyright (C) 2010 Jean-Francois Moine (http://moinejf.free.fr)
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  *Notes: * t613  + tas5130A
21  *	* Focus to light do not balance well as in win.
22  *	  Quality in win is not good, but its kinda better.
23  *	 * Fix some "extraneous bytes", most of apps will show the image anyway
24  *	 * Gamma table, is there, but its really doing something?
25  *	 * 7~8 Fps, its ok, max on win its 10.
26  *			Costantino Leandro
27  */
28 
29 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
30 
31 #define MODULE_NAME "t613"
32 
33 #include <linux/input.h>
34 #include <linux/slab.h>
35 #include "gspca.h"
36 
37 #define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0)
38 
39 MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
40 MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
41 MODULE_LICENSE("GPL");
42 
43 struct sd {
44 	struct gspca_dev gspca_dev;	/* !! must be the first item */
45 
46 	u8 brightness;
47 	u8 contrast;
48 	u8 colors;
49 	u8 autogain;
50 	u8 gamma;
51 	u8 sharpness;
52 	u8 freq;
53 	u8 red_gain;
54 	u8 blue_gain;
55 	u8 green_gain;
56 	u8 awb; /* set default r/g/b and activate */
57 	u8 mirror;
58 	u8 effect;
59 
60 	u8 sensor;
61 	u8 button_pressed;
62 };
63 enum sensors {
64 	SENSOR_OM6802,
65 	SENSOR_OTHER,
66 	SENSOR_TAS5130A,
67 	SENSOR_LT168G,		/* must verify if this is the actual model */
68 };
69 
70 /* V4L2 controls supported by the driver */
71 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
72 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
73 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
74 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
75 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
76 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
77 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val);
78 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val);
79 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
80 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
81 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
82 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
83 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
84 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
85 
86 static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val);
87 static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val);
88 static int sd_setblue_gain(struct gspca_dev *gspca_dev, __s32 val);
89 static int sd_getblue_gain(struct gspca_dev *gspca_dev, __s32 *val);
90 static int sd_setred_gain(struct gspca_dev *gspca_dev, __s32 val);
91 static int sd_getred_gain(struct gspca_dev *gspca_dev, __s32 *val);
92 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
93 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
94 
95 static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val);
96 static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val);
97 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val);
98 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
99 
100 static const struct ctrl sd_ctrls[] = {
101 	{
102 	 {
103 	  .id = V4L2_CID_BRIGHTNESS,
104 	  .type = V4L2_CTRL_TYPE_INTEGER,
105 	  .name = "Brightness",
106 	  .minimum = 0,
107 	  .maximum = 14,
108 	  .step = 1,
109 #define BRIGHTNESS_DEF 8
110 	  .default_value = BRIGHTNESS_DEF,
111 	  },
112 	 .set = sd_setbrightness,
113 	 .get = sd_getbrightness,
114 	 },
115 	{
116 	 {
117 	  .id = V4L2_CID_CONTRAST,
118 	  .type = V4L2_CTRL_TYPE_INTEGER,
119 	  .name = "Contrast",
120 	  .minimum = 0,
121 	  .maximum = 0x0d,
122 	  .step = 1,
123 #define CONTRAST_DEF 0x07
124 	  .default_value = CONTRAST_DEF,
125 	  },
126 	 .set = sd_setcontrast,
127 	 .get = sd_getcontrast,
128 	 },
129 	{
130 	 {
131 	  .id = V4L2_CID_SATURATION,
132 	  .type = V4L2_CTRL_TYPE_INTEGER,
133 	  .name = "Color",
134 	  .minimum = 0,
135 	  .maximum = 0x0f,
136 	  .step = 1,
137 #define COLORS_DEF 0x05
138 	  .default_value = COLORS_DEF,
139 	  },
140 	 .set = sd_setcolors,
141 	 .get = sd_getcolors,
142 	 },
143 #define GAMMA_MAX 16
144 #define GAMMA_DEF 10
145 	{
146 	 {
147 	  .id = V4L2_CID_GAMMA,	/* (gamma on win) */
148 	  .type = V4L2_CTRL_TYPE_INTEGER,
149 	  .name = "Gamma",
150 	  .minimum = 0,
151 	  .maximum = GAMMA_MAX - 1,
152 	  .step = 1,
153 	  .default_value = GAMMA_DEF,
154 	  },
155 	 .set = sd_setgamma,
156 	 .get = sd_getgamma,
157 	 },
158 	{
159 	 {
160 	  .id = V4L2_CID_BACKLIGHT_COMPENSATION, /* Activa lowlight,
161 				 * some apps dont bring up the
162 				 * backligth_compensation control) */
163 	  .type = V4L2_CTRL_TYPE_INTEGER,
164 	  .name = "Low Light",
165 	  .minimum = 0,
166 	  .maximum = 1,
167 	  .step = 1,
168 #define AUTOGAIN_DEF 0x01
169 	  .default_value = AUTOGAIN_DEF,
170 	  },
171 	 .set = sd_setlowlight,
172 	 .get = sd_getlowlight,
173 	 },
174 	{
175 	 {
176 	  .id = V4L2_CID_HFLIP,
177 	  .type = V4L2_CTRL_TYPE_BOOLEAN,
178 	  .name = "Mirror Image",
179 	  .minimum = 0,
180 	  .maximum = 1,
181 	  .step = 1,
182 #define MIRROR_DEF 0
183 	  .default_value = MIRROR_DEF,
184 	  },
185 	 .set = sd_setmirror,
186 	 .get = sd_getmirror
187 	},
188 	{
189 	 {
190 	  .id = V4L2_CID_POWER_LINE_FREQUENCY,
191 	  .type = V4L2_CTRL_TYPE_MENU,
192 	  .name = "Light Frequency Filter",
193 	  .minimum = 1,		/* 1 -> 0x50, 2->0x60 */
194 	  .maximum = 2,
195 	  .step = 1,
196 #define FREQ_DEF 1
197 	  .default_value = FREQ_DEF,
198 	  },
199 	 .set = sd_setfreq,
200 	 .get = sd_getfreq},
201 
202 	{
203 	 {
204 	  .id =  V4L2_CID_AUTO_WHITE_BALANCE,
205 	  .type = V4L2_CTRL_TYPE_INTEGER,
206 	  .name = "Auto White Balance",
207 	  .minimum = 0,
208 	  .maximum = 1,
209 	  .step = 1,
210 #define AWB_DEF 0
211 	  .default_value = AWB_DEF,
212 	  },
213 	 .set = sd_setawb,
214 	 .get = sd_getawb
215 	},
216 	{
217 	 {
218 	  .id = V4L2_CID_SHARPNESS,
219 	  .type = V4L2_CTRL_TYPE_INTEGER,
220 	  .name = "Sharpness",
221 	  .minimum = 0,
222 	  .maximum = 15,
223 	  .step = 1,
224 #define SHARPNESS_DEF 0x06
225 	  .default_value = SHARPNESS_DEF,
226 	  },
227 	 .set = sd_setsharpness,
228 	 .get = sd_getsharpness,
229 	 },
230 	{
231 	 {
232 	  .id = V4L2_CID_EFFECTS,
233 	  .type = V4L2_CTRL_TYPE_MENU,
234 	  .name = "Webcam Effects",
235 	  .minimum = 0,
236 	  .maximum = 4,
237 	  .step = 1,
238 #define EFFECTS_DEF 0
239 	  .default_value = EFFECTS_DEF,
240 	  },
241 	 .set = sd_seteffect,
242 	 .get = sd_geteffect
243 	},
244 	{
245 	 {
246 	    .id      = V4L2_CID_BLUE_BALANCE,
247 	    .type    = V4L2_CTRL_TYPE_INTEGER,
248 	    .name    = "Blue Balance",
249 	    .minimum = 0x10,
250 	    .maximum = 0x40,
251 	    .step    = 1,
252 #define BLUE_GAIN_DEF 0x20
253 	    .default_value = BLUE_GAIN_DEF,
254 	 },
255 	.set = sd_setblue_gain,
256 	.get = sd_getblue_gain,
257 	},
258 	{
259 	 {
260 	    .id      = V4L2_CID_RED_BALANCE,
261 	    .type    = V4L2_CTRL_TYPE_INTEGER,
262 	    .name    = "Red Balance",
263 	    .minimum = 0x10,
264 	    .maximum = 0x40,
265 	    .step    = 1,
266 #define RED_GAIN_DEF 0x20
267 	    .default_value = RED_GAIN_DEF,
268 	 },
269 	.set = sd_setred_gain,
270 	.get = sd_getred_gain,
271 	},
272 	{
273 	 {
274 	    .id      = V4L2_CID_GAIN,
275 	    .type    = V4L2_CTRL_TYPE_INTEGER,
276 	    .name    = "Gain",
277 	    .minimum = 0x10,
278 	    .maximum = 0x40,
279 	    .step    = 1,
280 #define GAIN_DEF  0x20
281 	    .default_value = GAIN_DEF,
282 	 },
283 	.set = sd_setgain,
284 	.get = sd_getgain,
285 	},
286 };
287 
288 static const struct v4l2_pix_format vga_mode_t16[] = {
289 	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
290 		.bytesperline = 160,
291 		.sizeimage = 160 * 120 * 4 / 8 + 590,
292 		.colorspace = V4L2_COLORSPACE_JPEG,
293 		.priv = 4},
294 	{176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
295 		.bytesperline = 176,
296 		.sizeimage = 176 * 144 * 3 / 8 + 590,
297 		.colorspace = V4L2_COLORSPACE_JPEG,
298 		.priv = 3},
299 	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
300 		.bytesperline = 320,
301 		.sizeimage = 320 * 240 * 3 / 8 + 590,
302 		.colorspace = V4L2_COLORSPACE_JPEG,
303 		.priv = 2},
304 	{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
305 		.bytesperline = 352,
306 		.sizeimage = 352 * 288 * 3 / 8 + 590,
307 		.colorspace = V4L2_COLORSPACE_JPEG,
308 		.priv = 1},
309 	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
310 		.bytesperline = 640,
311 		.sizeimage = 640 * 480 * 3 / 8 + 590,
312 		.colorspace = V4L2_COLORSPACE_JPEG,
313 		.priv = 0},
314 };
315 
316 /* sensor specific data */
317 struct additional_sensor_data {
318 	const u8 n3[6];
319 	const u8 *n4, n4sz;
320 	const u8 reg80, reg8e;
321 	const u8 nset8[6];
322 	const u8 data1[10];
323 	const u8 data2[9];
324 	const u8 data3[9];
325 	const u8 data5[6];
326 	const u8 stream[4];
327 };
328 
329 static const u8 n4_om6802[] = {
330 	0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
331 	0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
332 	0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
333 	0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
334 	0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
335 	0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
336 	0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
337 	0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
338 	0xac, 0x84, 0xad, 0x86, 0xaf, 0x46
339 };
340 static const u8 n4_other[] = {
341 	0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
342 	0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
343 	0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
344 	0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
345 	0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
346 	0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
347 	0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
348 	0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00
349 };
350 static const u8 n4_tas5130a[] = {
351 	0x80, 0x3c, 0x81, 0x68, 0x83, 0xa0, 0x84, 0x20,
352 	0x8a, 0x68, 0x8b, 0x58, 0x8c, 0x88, 0x8e, 0xb4,
353 	0x8f, 0x24, 0xa1, 0xb1, 0xa2, 0x30, 0xa5, 0x10,
354 	0xa6, 0x4a, 0xae, 0x03, 0xb1, 0x44, 0xb2, 0x08,
355 	0xb7, 0x06, 0xb9, 0xe7, 0xbb, 0xc4, 0xbc, 0x4a,
356 	0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8,
357 	0xc6, 0xda
358 };
359 static const u8 n4_lt168g[] = {
360 	0x66, 0x01, 0x7f, 0x00, 0x80, 0x7c, 0x81, 0x28,
361 	0x83, 0x44, 0x84, 0x20, 0x86, 0x20, 0x8a, 0x70,
362 	0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xa0, 0x8e, 0xb3,
363 	0x8f, 0x24, 0xa1, 0xb0, 0xa2, 0x38, 0xa5, 0x20,
364 	0xa6, 0x4a, 0xa8, 0xe8, 0xaf, 0x38, 0xb0, 0x68,
365 	0xb1, 0x44, 0xb2, 0x88, 0xbb, 0x86, 0xbd, 0x40,
366 	0xbe, 0x26, 0xc1, 0x05, 0xc2, 0x88, 0xc5, 0xc0,
367 	0xda, 0x8e, 0xdb, 0xca, 0xdc, 0xa8, 0xdd, 0x8c,
368 	0xde, 0x44, 0xdf, 0x0c, 0xe9, 0x80
369 };
370 
371 static const struct additional_sensor_data sensor_data[] = {
372 [SENSOR_OM6802] = {
373 	.n3 =
374 		{0x61, 0x68, 0x65, 0x0a, 0x60, 0x04},
375 	.n4 = n4_om6802,
376 	.n4sz = sizeof n4_om6802,
377 	.reg80 = 0x3c,
378 	.reg8e = 0x33,
379 	.nset8 = {0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00},
380 	.data1 =
381 		{0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
382 		 0xb3, 0xfc},
383 	.data2 =
384 		{0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
385 		 0xff},
386 	.data3 =
387 		{0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
388 		 0xff},
389 	.data5 =	/* this could be removed later */
390 		{0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
391 	.stream =
392 		{0x0b, 0x04, 0x0a, 0x78},
393     },
394 [SENSOR_OTHER] = {
395 	.n3 =
396 		{0x61, 0xc2, 0x65, 0x88, 0x60, 0x00},
397 	.n4 = n4_other,
398 	.n4sz = sizeof n4_other,
399 	.reg80 = 0xac,
400 	.reg8e = 0xb8,
401 	.nset8 = {0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00},
402 	.data1 =
403 		{0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
404 		 0xe8, 0xfc},
405 	.data2 =
406 		{0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
407 		 0xd9},
408 	.data3 =
409 		{0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
410 		 0xd9},
411 	.data5 =
412 		{0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
413 	.stream =
414 		{0x0b, 0x04, 0x0a, 0x00},
415     },
416 [SENSOR_TAS5130A] = {
417 	.n3 =
418 		{0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08},
419 	.n4 = n4_tas5130a,
420 	.n4sz = sizeof n4_tas5130a,
421 	.reg80 = 0x3c,
422 	.reg8e = 0xb4,
423 	.nset8 = {0xa8, 0xf0, 0xc6, 0xda, 0xc0, 0x00},
424 	.data1 =
425 		{0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
426 		 0xc8, 0xfc},
427 	.data2 =
428 		{0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
429 		 0xe0},
430 	.data3 =
431 		{0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
432 		 0xe0},
433 	.data5 =
434 		{0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
435 	.stream =
436 		{0x0b, 0x04, 0x0a, 0x40},
437     },
438 [SENSOR_LT168G] = {
439 	.n3 = {0x61, 0xc2, 0x65, 0x68, 0x60, 0x00},
440 	.n4 = n4_lt168g,
441 	.n4sz = sizeof n4_lt168g,
442 	.reg80 = 0x7c,
443 	.reg8e = 0xb3,
444 	.nset8 = {0xa8, 0xf0, 0xc6, 0xba, 0xc0, 0x00},
445 	.data1 = {0xc0, 0x38, 0x08, 0x10, 0xc0, 0x30, 0x10, 0x40,
446 		 0xb0, 0xf4},
447 	.data2 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
448 		 0xff},
449 	.data3 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
450 		 0xff},
451 	.data5 = {0x0c, 0x03, 0xab, 0x4b, 0x81, 0x2b},
452 	.stream = {0x0b, 0x04, 0x0a, 0x28},
453     },
454 };
455 
456 #define MAX_EFFECTS 7
457 /* easily done by soft, this table could be removed,
458  * i keep it here just in case */
459 static char *effects_control[MAX_EFFECTS] = {
460 	"Normal",
461 	"Emboss",		/* disabled */
462 	"Monochrome",
463 	"Sepia",
464 	"Sketch",
465 	"Sun Effect",		/* disabled */
466 	"Negative",
467 };
468 static const u8 effects_table[MAX_EFFECTS][6] = {
469 	{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00},	/* Normal */
470 	{0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04},	/* Repujar */
471 	{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20},	/* Monochrome */
472 	{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80},	/* Sepia */
473 	{0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02},	/* Croquis */
474 	{0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10},	/* Sun Effect */
475 	{0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40},	/* Negative */
476 };
477 
478 static const u8 gamma_table[GAMMA_MAX][17] = {
479 /* gamma table from cam1690.ini */
480 	{0x00, 0x00, 0x01, 0x04, 0x08, 0x0e, 0x16, 0x21,	/* 0 */
481 	 0x2e, 0x3d, 0x50, 0x65, 0x7d, 0x99, 0xb8, 0xdb,
482 	 0xff},
483 	{0x00, 0x01, 0x03, 0x08, 0x0e, 0x16, 0x21, 0x2d,	/* 1 */
484 	 0x3c, 0x4d, 0x60, 0x75, 0x8d, 0xa6, 0xc2, 0xe1,
485 	 0xff},
486 	{0x00, 0x01, 0x05, 0x0b, 0x12, 0x1c, 0x28, 0x35,	/* 2 */
487 	 0x45, 0x56, 0x69, 0x7e, 0x95, 0xad, 0xc7, 0xe3,
488 	 0xff},
489 	{0x00, 0x02, 0x07, 0x0f, 0x18, 0x24, 0x30, 0x3f,	/* 3 */
490 	 0x4f, 0x61, 0x73, 0x88, 0x9d, 0xb4, 0xcd, 0xe6,
491 	 0xff},
492 	{0x00, 0x04, 0x0b, 0x15, 0x20, 0x2d, 0x3b, 0x4a,	/* 4 */
493 	 0x5b, 0x6c, 0x7f, 0x92, 0xa7, 0xbc, 0xd2, 0xe9,
494 	 0xff},
495 	{0x00, 0x07, 0x11, 0x15, 0x20, 0x2d, 0x48, 0x58,	/* 5 */
496 	 0x68, 0x79, 0x8b, 0x9d, 0xb0, 0xc4, 0xd7, 0xec,
497 	 0xff},
498 	{0x00, 0x0c, 0x1a, 0x29, 0x38, 0x47, 0x57, 0x67,	/* 6 */
499 	 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
500 	 0xff},
501 	{0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,	/* 7 */
502 	 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
503 	 0xff},
504 	{0x00, 0x15, 0x27, 0x38, 0x49, 0x59, 0x69, 0x79,	/* 8 */
505 	 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe2, 0xf0,
506 	 0xff},
507 	{0x00, 0x1c, 0x30, 0x43, 0x54, 0x65, 0x75, 0x84,	/* 9 */
508 	 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd8, 0xe5, 0xf2,
509 	 0xff},
510 	{0x00, 0x24, 0x3b, 0x4f, 0x60, 0x70, 0x80, 0x8e,	/* 10 */
511 	 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xdc, 0xe8, 0xf3,
512 	 0xff},
513 	{0x00, 0x2a, 0x3c, 0x5d, 0x6e, 0x7e, 0x8d, 0x9b,	/* 11 */
514 	 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
515 	 0xff},
516 	{0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8,	/* 12 */
517 	 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
518 	 0xff},
519 	{0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7,	/* 13 */
520 	 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
521 	 0xff},
522 	{0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6,	/* 14 */
523 	 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
524 	 0xff},
525 	{0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8,	/* 15 */
526 	 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
527 	 0xff}
528 };
529 
530 static const u8 tas5130a_sensor_init[][8] = {
531 	{0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
532 	{0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
533 	{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
534 };
535 
536 static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
537 
538 /* read 1 byte */
reg_r(struct gspca_dev * gspca_dev,u16 index)539 static u8 reg_r(struct gspca_dev *gspca_dev,
540 		   u16 index)
541 {
542 	usb_control_msg(gspca_dev->dev,
543 			usb_rcvctrlpipe(gspca_dev->dev, 0),
544 			0,		/* request */
545 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
546 			0,		/* value */
547 			index,
548 			gspca_dev->usb_buf, 1, 500);
549 	return gspca_dev->usb_buf[0];
550 }
551 
reg_w(struct gspca_dev * gspca_dev,u16 index)552 static void reg_w(struct gspca_dev *gspca_dev,
553 		  u16 index)
554 {
555 	usb_control_msg(gspca_dev->dev,
556 			usb_sndctrlpipe(gspca_dev->dev, 0),
557 			0,
558 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
559 			0, index,
560 			NULL, 0, 500);
561 }
562 
reg_w_buf(struct gspca_dev * gspca_dev,const u8 * buffer,u16 len)563 static void reg_w_buf(struct gspca_dev *gspca_dev,
564 		  const u8 *buffer, u16 len)
565 {
566 	if (len <= USB_BUF_SZ) {
567 		memcpy(gspca_dev->usb_buf, buffer, len);
568 		usb_control_msg(gspca_dev->dev,
569 				usb_sndctrlpipe(gspca_dev->dev, 0),
570 				0,
571 			   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
572 				0x01, 0,
573 				gspca_dev->usb_buf, len, 500);
574 	} else {
575 		u8 *tmpbuf;
576 
577 		tmpbuf = kmemdup(buffer, len, GFP_KERNEL);
578 		if (!tmpbuf) {
579 			pr_err("Out of memory\n");
580 			return;
581 		}
582 		usb_control_msg(gspca_dev->dev,
583 				usb_sndctrlpipe(gspca_dev->dev, 0),
584 				0,
585 			   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
586 				0x01, 0,
587 				tmpbuf, len, 500);
588 		kfree(tmpbuf);
589 	}
590 }
591 
592 /* write values to consecutive registers */
reg_w_ixbuf(struct gspca_dev * gspca_dev,u8 reg,const u8 * buffer,u16 len)593 static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
594 			u8 reg,
595 			const u8 *buffer, u16 len)
596 {
597 	int i;
598 	u8 *p, *tmpbuf;
599 
600 	if (len * 2 <= USB_BUF_SZ) {
601 		p = tmpbuf = gspca_dev->usb_buf;
602 	} else {
603 		p = tmpbuf = kmalloc(len * 2, GFP_KERNEL);
604 		if (!tmpbuf) {
605 			pr_err("Out of memory\n");
606 			return;
607 		}
608 	}
609 	i = len;
610 	while (--i >= 0) {
611 		*p++ = reg++;
612 		*p++ = *buffer++;
613 	}
614 	usb_control_msg(gspca_dev->dev,
615 			usb_sndctrlpipe(gspca_dev->dev, 0),
616 			0,
617 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
618 			0x01, 0,
619 			tmpbuf, len * 2, 500);
620 	if (len * 2 > USB_BUF_SZ)
621 		kfree(tmpbuf);
622 }
623 
om6802_sensor_init(struct gspca_dev * gspca_dev)624 static void om6802_sensor_init(struct gspca_dev *gspca_dev)
625 {
626 	int i;
627 	const u8 *p;
628 	u8 byte;
629 	u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
630 	static const u8 sensor_init[] = {
631 		0xdf, 0x6d,
632 		0xdd, 0x18,
633 		0x5a, 0xe0,
634 		0x5c, 0x07,
635 		0x5d, 0xb0,
636 		0x5e, 0x1e,
637 		0x60, 0x71,
638 		0xef, 0x00,
639 		0xe9, 0x00,
640 		0xea, 0x00,
641 		0x90, 0x24,
642 		0x91, 0xb2,
643 		0x82, 0x32,
644 		0xfd, 0x41,
645 		0x00			/* table end */
646 	};
647 
648 	reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
649 	msleep(100);
650 	i = 4;
651 	while (--i > 0) {
652 		byte = reg_r(gspca_dev, 0x0060);
653 		if (!(byte & 0x01))
654 			break;
655 		msleep(100);
656 	}
657 	byte = reg_r(gspca_dev, 0x0063);
658 	if (byte != 0x17) {
659 		pr_err("Bad sensor reset %02x\n", byte);
660 		/* continue? */
661 	}
662 
663 	p = sensor_init;
664 	while (*p != 0) {
665 		val[1] = *p++;
666 		val[3] = *p++;
667 		if (*p == 0)
668 			reg_w(gspca_dev, 0x3c80);
669 		reg_w_buf(gspca_dev, val, sizeof val);
670 		i = 4;
671 		while (--i >= 0) {
672 			msleep(15);
673 			byte = reg_r(gspca_dev, 0x60);
674 			if (!(byte & 0x01))
675 				break;
676 		}
677 	}
678 	msleep(15);
679 	reg_w(gspca_dev, 0x3c80);
680 }
681 
682 /* this function is called at probe time */
sd_config(struct gspca_dev * gspca_dev,const struct usb_device_id * id)683 static int sd_config(struct gspca_dev *gspca_dev,
684 		     const struct usb_device_id *id)
685 {
686 	struct sd *sd = (struct sd *) gspca_dev;
687 	struct cam *cam;
688 
689 	cam = &gspca_dev->cam;
690 
691 	cam->cam_mode = vga_mode_t16;
692 	cam->nmodes = ARRAY_SIZE(vga_mode_t16);
693 
694 	sd->brightness = BRIGHTNESS_DEF;
695 	sd->contrast = CONTRAST_DEF;
696 	sd->colors = COLORS_DEF;
697 	sd->gamma = GAMMA_DEF;
698 	sd->autogain = AUTOGAIN_DEF;
699 	sd->mirror = MIRROR_DEF;
700 	sd->freq = FREQ_DEF;
701 	sd->awb = AWB_DEF;
702 	sd->sharpness = SHARPNESS_DEF;
703 	sd->effect = EFFECTS_DEF;
704 	sd->red_gain = RED_GAIN_DEF;
705 	sd->blue_gain = BLUE_GAIN_DEF;
706 	sd->green_gain = GAIN_DEF * 3 - RED_GAIN_DEF - BLUE_GAIN_DEF;
707 
708 	return 0;
709 }
710 
setbrightness(struct gspca_dev * gspca_dev)711 static void setbrightness(struct gspca_dev *gspca_dev)
712 {
713 	struct sd *sd = (struct sd *) gspca_dev;
714 	unsigned int brightness;
715 	u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
716 
717 	brightness = sd->brightness;
718 	if (brightness < 7) {
719 		set6[1] = 0x26;
720 		set6[3] = 0x70 - brightness * 0x10;
721 	} else {
722 		set6[3] = 0x00 + ((brightness - 7) * 0x10);
723 	}
724 
725 	reg_w_buf(gspca_dev, set6, sizeof set6);
726 }
727 
setcontrast(struct gspca_dev * gspca_dev)728 static void setcontrast(struct gspca_dev *gspca_dev)
729 {
730 	struct sd *sd = (struct sd *) gspca_dev;
731 	unsigned int contrast = sd->contrast;
732 	u16 reg_to_write;
733 
734 	if (contrast < 7)
735 		reg_to_write = 0x8ea9 - contrast * 0x200;
736 	else
737 		reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
738 
739 	reg_w(gspca_dev, reg_to_write);
740 }
741 
setcolors(struct gspca_dev * gspca_dev)742 static void setcolors(struct gspca_dev *gspca_dev)
743 {
744 	struct sd *sd = (struct sd *) gspca_dev;
745 	u16 reg_to_write;
746 
747 	reg_to_write = 0x80bb + sd->colors * 0x100;	/* was 0xc0 */
748 	reg_w(gspca_dev, reg_to_write);
749 }
750 
setgamma(struct gspca_dev * gspca_dev)751 static void setgamma(struct gspca_dev *gspca_dev)
752 {
753 	struct sd *sd = (struct sd *) gspca_dev;
754 
755 	PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
756 	reg_w_ixbuf(gspca_dev, 0x90,
757 		gamma_table[sd->gamma], sizeof gamma_table[0]);
758 }
759 
setRGB(struct gspca_dev * gspca_dev)760 static void setRGB(struct gspca_dev *gspca_dev)
761 {
762 	struct sd *sd = (struct sd *) gspca_dev;
763 	u8 all_gain_reg[6] =
764 		{0x87, 0x00, 0x88, 0x00, 0x89, 0x00};
765 
766 	all_gain_reg[1] = sd->red_gain;
767 	all_gain_reg[3] = sd->blue_gain;
768 	all_gain_reg[5] = sd->green_gain;
769 	reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg);
770 }
771 
772 /* Generic fnc for r/b balance, exposure and awb */
setawb(struct gspca_dev * gspca_dev)773 static void setawb(struct gspca_dev *gspca_dev)
774 {
775 	struct sd *sd = (struct sd *) gspca_dev;
776 	u16 reg80;
777 
778 	reg80 = (sensor_data[sd->sensor].reg80 << 8) | 0x80;
779 
780 	/* on awb leave defaults values */
781 	if (!sd->awb) {
782 		/* shoud we wait here.. */
783 		/* update and reset RGB gains with webcam values */
784 		sd->red_gain = reg_r(gspca_dev, 0x0087);
785 		sd->blue_gain = reg_r(gspca_dev, 0x0088);
786 		sd->green_gain = reg_r(gspca_dev, 0x0089);
787 		reg80 &= ~0x0400;		/* AWB off */
788 	}
789 	reg_w(gspca_dev, reg80);
790 	reg_w(gspca_dev, reg80);
791 }
792 
init_gains(struct gspca_dev * gspca_dev)793 static void init_gains(struct gspca_dev *gspca_dev)
794 {
795 	struct sd *sd = (struct sd *) gspca_dev;
796 	u16 reg80;
797 	u8 all_gain_reg[8] =
798 		{0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x80, 0x00};
799 
800 	all_gain_reg[1] = sd->red_gain;
801 	all_gain_reg[3] = sd->blue_gain;
802 	all_gain_reg[5] = sd->green_gain;
803 	reg80 = sensor_data[sd->sensor].reg80;
804 	if (!sd->awb)
805 		reg80 &= ~0x04;
806 	all_gain_reg[7] = reg80;
807 	reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg);
808 
809 	reg_w(gspca_dev, (sd->red_gain  << 8) + 0x87);
810 	reg_w(gspca_dev, (sd->blue_gain << 8) + 0x88);
811 	reg_w(gspca_dev, (sd->green_gain  << 8) + 0x89);
812 }
813 
setsharpness(struct gspca_dev * gspca_dev)814 static void setsharpness(struct gspca_dev *gspca_dev)
815 {
816 	struct sd *sd = (struct sd *) gspca_dev;
817 	u16 reg_to_write;
818 
819 	reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
820 
821 	reg_w(gspca_dev, reg_to_write);
822 }
823 
setfreq(struct gspca_dev * gspca_dev)824 static void setfreq(struct gspca_dev *gspca_dev)
825 {
826 	struct sd *sd = (struct sd *) gspca_dev;
827 	u8 reg66;
828 	u8 freq[4] = { 0x66, 0x00, 0xa8, 0xe8 };
829 
830 	switch (sd->sensor) {
831 	case SENSOR_LT168G:
832 		if (sd->freq != 0)
833 			freq[3] = 0xa8;
834 		reg66 = 0x41;
835 		break;
836 	case SENSOR_OM6802:
837 		reg66 = 0xca;
838 		break;
839 	default:
840 		reg66 = 0x40;
841 		break;
842 	}
843 	switch (sd->freq) {
844 	case 0:				/* no flicker */
845 		freq[3] = 0xf0;
846 		break;
847 	case 2:				/* 60Hz */
848 		reg66 &= ~0x40;
849 		break;
850 	}
851 	freq[1] = reg66;
852 
853 	reg_w_buf(gspca_dev, freq, sizeof freq);
854 }
855 
856 /* this function is called at probe and resume time */
sd_init(struct gspca_dev * gspca_dev)857 static int sd_init(struct gspca_dev *gspca_dev)
858 {
859 	/* some of this registers are not really neded, because
860 	 * they are overriden by setbrigthness, setcontrast, etc,
861 	 * but wont hurt anyway, and can help someone with similar webcam
862 	 * to see the initial parameters.*/
863 	struct sd *sd = (struct sd *) gspca_dev;
864 	const struct additional_sensor_data *sensor;
865 	int i;
866 	u16 sensor_id;
867 	u8 test_byte = 0;
868 
869 	static const u8 read_indexs[] =
870 		{ 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
871 		  0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 };
872 	static const u8 n1[] =
873 			{0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
874 	static const u8 n2[] =
875 			{0x08, 0x00};
876 
877 	sensor_id = (reg_r(gspca_dev, 0x06) << 8)
878 			| reg_r(gspca_dev, 0x07);
879 	switch (sensor_id & 0xff0f) {
880 	case 0x0801:
881 		PDEBUG(D_PROBE, "sensor tas5130a");
882 		sd->sensor = SENSOR_TAS5130A;
883 		break;
884 	case 0x0802:
885 		PDEBUG(D_PROBE, "sensor lt168g");
886 		sd->sensor = SENSOR_LT168G;
887 		break;
888 	case 0x0803:
889 		PDEBUG(D_PROBE, "sensor 'other'");
890 		sd->sensor = SENSOR_OTHER;
891 		break;
892 	case 0x0807:
893 		PDEBUG(D_PROBE, "sensor om6802");
894 		sd->sensor = SENSOR_OM6802;
895 		break;
896 	default:
897 		pr_err("unknown sensor %04x\n", sensor_id);
898 		return -EINVAL;
899 	}
900 
901 	if (sd->sensor == SENSOR_OM6802) {
902 		reg_w_buf(gspca_dev, n1, sizeof n1);
903 		i = 5;
904 		while (--i >= 0) {
905 			reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
906 			test_byte = reg_r(gspca_dev, 0x0063);
907 			msleep(100);
908 			if (test_byte == 0x17)
909 				break;		/* OK */
910 		}
911 		if (i < 0) {
912 			pr_err("Bad sensor reset %02x\n", test_byte);
913 			return -EIO;
914 		}
915 		reg_w_buf(gspca_dev, n2, sizeof n2);
916 	}
917 
918 	i = 0;
919 	while (read_indexs[i] != 0x00) {
920 		test_byte = reg_r(gspca_dev, read_indexs[i]);
921 		PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
922 		       test_byte);
923 		i++;
924 	}
925 
926 	sensor = &sensor_data[sd->sensor];
927 	reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3);
928 	reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz);
929 
930 	if (sd->sensor == SENSOR_LT168G) {
931 		test_byte = reg_r(gspca_dev, 0x80);
932 		PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
933 		       test_byte);
934 		reg_w(gspca_dev, 0x6c80);
935 	}
936 
937 	reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
938 	reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
939 	reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
940 
941 	reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
942 	reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
943 	reg_w(gspca_dev, (sensor->reg8e << 8) + 0x8e);
944 
945 	setbrightness(gspca_dev);
946 	setcontrast(gspca_dev);
947 	setgamma(gspca_dev);
948 	setcolors(gspca_dev);
949 	setsharpness(gspca_dev);
950 	init_gains(gspca_dev);
951 	setfreq(gspca_dev);
952 
953 	reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5);
954 	reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8);
955 	reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
956 
957 	if (sd->sensor == SENSOR_LT168G) {
958 		test_byte = reg_r(gspca_dev, 0x80);
959 		PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", 0x80,
960 		       test_byte);
961 		reg_w(gspca_dev, 0x6c80);
962 	}
963 
964 	reg_w_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
965 	reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
966 	reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
967 
968 	return 0;
969 }
970 
setmirror(struct gspca_dev * gspca_dev)971 static void setmirror(struct gspca_dev *gspca_dev)
972 {
973 	struct sd *sd = (struct sd *) gspca_dev;
974 	u8 hflipcmd[8] =
975 		{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
976 
977 	if (sd->mirror)
978 		hflipcmd[3] = 0x01;
979 
980 	reg_w_buf(gspca_dev, hflipcmd, sizeof hflipcmd);
981 }
982 
seteffect(struct gspca_dev * gspca_dev)983 static void seteffect(struct gspca_dev *gspca_dev)
984 {
985 	struct sd *sd = (struct sd *) gspca_dev;
986 
987 	reg_w_buf(gspca_dev, effects_table[sd->effect],
988 				sizeof effects_table[0]);
989 	if (sd->effect == 1 || sd->effect == 5) {
990 		PDEBUG(D_CONF,
991 		       "This effect have been disabled for webcam \"safety\"");
992 		return;
993 	}
994 
995 	if (sd->effect == 1 || sd->effect == 4)
996 		reg_w(gspca_dev, 0x4aa6);
997 	else
998 		reg_w(gspca_dev, 0xfaa6);
999 }
1000 
1001 /* Is this really needed?
1002  * i added some module parameters for test with some users */
poll_sensor(struct gspca_dev * gspca_dev)1003 static void poll_sensor(struct gspca_dev *gspca_dev)
1004 {
1005 	static const u8 poll1[] =
1006 		{0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
1007 		 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
1008 		 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
1009 		 0x60, 0x14};
1010 	static const u8 poll2[] =
1011 		{0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
1012 		 0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
1013 	static const u8 noise03[] =	/* (some differences / ms-drv) */
1014 		{0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
1015 		 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
1016 		 0xc2, 0x80, 0xc3, 0x10};
1017 
1018 	PDEBUG(D_STREAM, "[Sensor requires polling]");
1019 	reg_w_buf(gspca_dev, poll1, sizeof poll1);
1020 	reg_w_buf(gspca_dev, poll2, sizeof poll2);
1021 	reg_w_buf(gspca_dev, noise03, sizeof noise03);
1022 }
1023 
sd_start(struct gspca_dev * gspca_dev)1024 static int sd_start(struct gspca_dev *gspca_dev)
1025 {
1026 	struct sd *sd = (struct sd *) gspca_dev;
1027 	const struct additional_sensor_data *sensor;
1028 	int i, mode;
1029 	u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
1030 	static const u8 t3[] =
1031 		{ 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
1032 
1033 	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
1034 	switch (mode) {
1035 	case 0:		/* 640x480 (0x00) */
1036 		break;
1037 	case 1:		/* 352x288 */
1038 		t2[1] = 0x40;
1039 		break;
1040 	case 2:		/* 320x240 */
1041 		t2[1] = 0x10;
1042 		break;
1043 	case 3:		/* 176x144 */
1044 		t2[1] = 0x50;
1045 		break;
1046 	default:
1047 /*	case 4:		 * 160x120 */
1048 		t2[1] = 0x20;
1049 		break;
1050 	}
1051 
1052 	switch (sd->sensor) {
1053 	case SENSOR_OM6802:
1054 		om6802_sensor_init(gspca_dev);
1055 		break;
1056 	case SENSOR_TAS5130A:
1057 		i = 0;
1058 		for (;;) {
1059 			reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
1060 					 sizeof tas5130a_sensor_init[0]);
1061 			if (i >= ARRAY_SIZE(tas5130a_sensor_init) - 1)
1062 				break;
1063 			i++;
1064 		}
1065 		reg_w(gspca_dev, 0x3c80);
1066 		/* just in case and to keep sync with logs (for mine) */
1067 		reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
1068 				 sizeof tas5130a_sensor_init[0]);
1069 		reg_w(gspca_dev, 0x3c80);
1070 		break;
1071 	}
1072 	sensor = &sensor_data[sd->sensor];
1073 	setfreq(gspca_dev);
1074 	reg_r(gspca_dev, 0x0012);
1075 	reg_w_buf(gspca_dev, t2, sizeof t2);
1076 	reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
1077 	reg_w(gspca_dev, 0x0013);
1078 	msleep(15);
1079 	reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
1080 	reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
1081 
1082 	if (sd->sensor == SENSOR_OM6802)
1083 		poll_sensor(gspca_dev);
1084 
1085 	return 0;
1086 }
1087 
sd_stopN(struct gspca_dev * gspca_dev)1088 static void sd_stopN(struct gspca_dev *gspca_dev)
1089 {
1090 	struct sd *sd = (struct sd *) gspca_dev;
1091 
1092 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
1093 			sizeof sensor_data[sd->sensor].stream);
1094 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
1095 			sizeof sensor_data[sd->sensor].stream);
1096 	if (sd->sensor == SENSOR_OM6802) {
1097 		msleep(20);
1098 		reg_w(gspca_dev, 0x0309);
1099 	}
1100 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1101 	/* If the last button state is pressed, release it now! */
1102 	if (sd->button_pressed) {
1103 		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1104 		input_sync(gspca_dev->input_dev);
1105 		sd->button_pressed = 0;
1106 	}
1107 #endif
1108 }
1109 
sd_pkt_scan(struct gspca_dev * gspca_dev,u8 * data,int len)1110 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1111 			u8 *data,			/* isoc packet */
1112 			int len)			/* iso packet length */
1113 {
1114 	struct sd *sd = (struct sd *) gspca_dev;
1115 	int pkt_type;
1116 
1117 	if (data[0] == 0x5a) {
1118 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1119 		if (len > 20) {
1120 			u8 state = (data[20] & 0x80) ? 1 : 0;
1121 			if (sd->button_pressed != state) {
1122 				input_report_key(gspca_dev->input_dev,
1123 						 KEY_CAMERA, state);
1124 				input_sync(gspca_dev->input_dev);
1125 				sd->button_pressed = state;
1126 			}
1127 		}
1128 #endif
1129 		/* Control Packet, after this came the header again,
1130 		 * but extra bytes came in the packet before this,
1131 		 * sometimes an EOF arrives, sometimes not... */
1132 		return;
1133 	}
1134 	data += 2;
1135 	len -= 2;
1136 	if (data[0] == 0xff && data[1] == 0xd8)
1137 		pkt_type = FIRST_PACKET;
1138 	else if (data[len - 2] == 0xff && data[len - 1] == 0xd9)
1139 		pkt_type = LAST_PACKET;
1140 	else
1141 		pkt_type = INTER_PACKET;
1142 	gspca_frame_add(gspca_dev, pkt_type, data, len);
1143 }
1144 
sd_setblue_gain(struct gspca_dev * gspca_dev,__s32 val)1145 static int sd_setblue_gain(struct gspca_dev *gspca_dev, __s32 val)
1146 {
1147 	struct sd *sd = (struct sd *) gspca_dev;
1148 
1149 	sd->blue_gain = val;
1150 	if (gspca_dev->streaming)
1151 		reg_w(gspca_dev, (val << 8) + 0x88);
1152 	return 0;
1153 }
1154 
sd_getblue_gain(struct gspca_dev * gspca_dev,__s32 * val)1155 static int sd_getblue_gain(struct gspca_dev *gspca_dev, __s32 *val)
1156 {
1157 	struct sd *sd = (struct sd *) gspca_dev;
1158 
1159 	*val = sd->blue_gain;
1160 	return 0;
1161 }
1162 
sd_setred_gain(struct gspca_dev * gspca_dev,__s32 val)1163 static int sd_setred_gain(struct gspca_dev *gspca_dev, __s32 val)
1164 {
1165 	struct sd *sd = (struct sd *) gspca_dev;
1166 
1167 	sd->red_gain = val;
1168 	if (gspca_dev->streaming)
1169 		reg_w(gspca_dev, (val << 8) + 0x87);
1170 
1171 	return 0;
1172 }
1173 
sd_getred_gain(struct gspca_dev * gspca_dev,__s32 * val)1174 static int sd_getred_gain(struct gspca_dev *gspca_dev, __s32 *val)
1175 {
1176 	struct sd *sd = (struct sd *) gspca_dev;
1177 
1178 	*val = sd->red_gain;
1179 	return 0;
1180 }
1181 
sd_setgain(struct gspca_dev * gspca_dev,__s32 val)1182 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1183 {
1184 	struct sd *sd = (struct sd *) gspca_dev;
1185 	u16 psg, nsg;
1186 
1187 	psg = sd->red_gain + sd->blue_gain + sd->green_gain;
1188 	nsg = val * 3;
1189 	sd->red_gain = sd->red_gain * nsg / psg;
1190 	if (sd->red_gain > 0x40)
1191 		sd->red_gain = 0x40;
1192 	else if (sd->red_gain < 0x10)
1193 		sd->red_gain = 0x10;
1194 	sd->blue_gain = sd->blue_gain * nsg / psg;
1195 	if (sd->blue_gain > 0x40)
1196 		sd->blue_gain = 0x40;
1197 	else if (sd->blue_gain < 0x10)
1198 		sd->blue_gain = 0x10;
1199 	sd->green_gain = sd->green_gain * nsg / psg;
1200 	if (sd->green_gain > 0x40)
1201 		sd->green_gain = 0x40;
1202 	else if (sd->green_gain < 0x10)
1203 		sd->green_gain = 0x10;
1204 
1205 	if (gspca_dev->streaming)
1206 		setRGB(gspca_dev);
1207 	return 0;
1208 }
1209 
sd_getgain(struct gspca_dev * gspca_dev,__s32 * val)1210 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1211 {
1212 	struct sd *sd = (struct sd *) gspca_dev;
1213 
1214 	*val = (sd->red_gain + sd->blue_gain + sd->green_gain) / 3;
1215 	return 0;
1216 }
1217 
sd_setbrightness(struct gspca_dev * gspca_dev,__s32 val)1218 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1219 {
1220 	struct sd *sd = (struct sd *) gspca_dev;
1221 
1222 	sd->brightness = val;
1223 	if (gspca_dev->streaming)
1224 		setbrightness(gspca_dev);
1225 	return 0;
1226 }
1227 
sd_getbrightness(struct gspca_dev * gspca_dev,__s32 * val)1228 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1229 {
1230 	struct sd *sd = (struct sd *) gspca_dev;
1231 
1232 	*val = sd->brightness;
1233 	return *val;
1234 }
1235 
sd_setawb(struct gspca_dev * gspca_dev,__s32 val)1236 static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val)
1237 {
1238 	struct sd *sd = (struct sd *) gspca_dev;
1239 
1240 	sd->awb = val;
1241 	if (gspca_dev->streaming)
1242 		setawb(gspca_dev);
1243 	return 0;
1244 }
1245 
sd_getawb(struct gspca_dev * gspca_dev,__s32 * val)1246 static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val)
1247 {
1248 	struct sd *sd = (struct sd *) gspca_dev;
1249 
1250 	*val = sd->awb;
1251 	return *val;
1252 }
1253 
sd_setmirror(struct gspca_dev * gspca_dev,__s32 val)1254 static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val)
1255 {
1256 	struct sd *sd = (struct sd *) gspca_dev;
1257 
1258 	sd->mirror = val;
1259 	if (gspca_dev->streaming)
1260 		setmirror(gspca_dev);
1261 	return 0;
1262 }
1263 
sd_getmirror(struct gspca_dev * gspca_dev,__s32 * val)1264 static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val)
1265 {
1266 	struct sd *sd = (struct sd *) gspca_dev;
1267 
1268 	*val = sd->mirror;
1269 	return *val;
1270 }
1271 
sd_seteffect(struct gspca_dev * gspca_dev,__s32 val)1272 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
1273 {
1274 	struct sd *sd = (struct sd *) gspca_dev;
1275 
1276 	sd->effect = val;
1277 	if (gspca_dev->streaming)
1278 		seteffect(gspca_dev);
1279 	return 0;
1280 }
1281 
sd_geteffect(struct gspca_dev * gspca_dev,__s32 * val)1282 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
1283 {
1284 	struct sd *sd = (struct sd *) gspca_dev;
1285 
1286 	*val = sd->effect;
1287 	return *val;
1288 }
1289 
sd_setcontrast(struct gspca_dev * gspca_dev,__s32 val)1290 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1291 {
1292 	struct sd *sd = (struct sd *) gspca_dev;
1293 
1294 	sd->contrast = val;
1295 	if (gspca_dev->streaming)
1296 		setcontrast(gspca_dev);
1297 	return 0;
1298 }
1299 
sd_getcontrast(struct gspca_dev * gspca_dev,__s32 * val)1300 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1301 {
1302 	struct sd *sd = (struct sd *) gspca_dev;
1303 
1304 	*val = sd->contrast;
1305 	return *val;
1306 }
1307 
sd_setcolors(struct gspca_dev * gspca_dev,__s32 val)1308 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1309 {
1310 	struct sd *sd = (struct sd *) gspca_dev;
1311 
1312 	sd->colors = val;
1313 	if (gspca_dev->streaming)
1314 		setcolors(gspca_dev);
1315 	return 0;
1316 }
1317 
sd_getcolors(struct gspca_dev * gspca_dev,__s32 * val)1318 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1319 {
1320 	struct sd *sd = (struct sd *) gspca_dev;
1321 
1322 	*val = sd->colors;
1323 	return 0;
1324 }
1325 
sd_setgamma(struct gspca_dev * gspca_dev,__s32 val)1326 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
1327 {
1328 	struct sd *sd = (struct sd *) gspca_dev;
1329 
1330 	sd->gamma = val;
1331 	if (gspca_dev->streaming)
1332 		setgamma(gspca_dev);
1333 	return 0;
1334 }
1335 
sd_getgamma(struct gspca_dev * gspca_dev,__s32 * val)1336 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
1337 {
1338 	struct sd *sd = (struct sd *) gspca_dev;
1339 
1340 	*val = sd->gamma;
1341 	return 0;
1342 }
1343 
sd_setfreq(struct gspca_dev * gspca_dev,__s32 val)1344 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1345 {
1346 	struct sd *sd = (struct sd *) gspca_dev;
1347 
1348 	sd->freq = val;
1349 	if (gspca_dev->streaming)
1350 		setfreq(gspca_dev);
1351 	return 0;
1352 }
1353 
sd_getfreq(struct gspca_dev * gspca_dev,__s32 * val)1354 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1355 {
1356 	struct sd *sd = (struct sd *) gspca_dev;
1357 
1358 	*val = sd->freq;
1359 	return 0;
1360 }
1361 
sd_setsharpness(struct gspca_dev * gspca_dev,__s32 val)1362 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1363 {
1364 	struct sd *sd = (struct sd *) gspca_dev;
1365 
1366 	sd->sharpness = val;
1367 	if (gspca_dev->streaming)
1368 		setsharpness(gspca_dev);
1369 	return 0;
1370 }
1371 
sd_getsharpness(struct gspca_dev * gspca_dev,__s32 * val)1372 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
1373 {
1374 	struct sd *sd = (struct sd *) gspca_dev;
1375 
1376 	*val = sd->sharpness;
1377 	return 0;
1378 }
1379 
1380 /* Low Light set  here......*/
sd_setlowlight(struct gspca_dev * gspca_dev,__s32 val)1381 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
1382 {
1383 	struct sd *sd = (struct sd *) gspca_dev;
1384 
1385 	sd->autogain = val;
1386 	if (val != 0)
1387 		reg_w(gspca_dev, 0xf48e);
1388 	else
1389 		reg_w(gspca_dev, 0xb48e);
1390 	return 0;
1391 }
1392 
sd_getlowlight(struct gspca_dev * gspca_dev,__s32 * val)1393 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
1394 {
1395 	struct sd *sd = (struct sd *) gspca_dev;
1396 
1397 	*val = sd->autogain;
1398 	return 0;
1399 }
1400 
sd_querymenu(struct gspca_dev * gspca_dev,struct v4l2_querymenu * menu)1401 static int sd_querymenu(struct gspca_dev *gspca_dev,
1402 			struct v4l2_querymenu *menu)
1403 {
1404 	static const char *freq_nm[3] = {"NoFliker", "50 Hz", "60 Hz"};
1405 
1406 	switch (menu->id) {
1407 	case V4L2_CID_POWER_LINE_FREQUENCY:
1408 		if ((unsigned) menu->index >= ARRAY_SIZE(freq_nm))
1409 			break;
1410 		strcpy((char *) menu->name, freq_nm[menu->index]);
1411 		return 0;
1412 	case V4L2_CID_EFFECTS:
1413 		if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
1414 			strlcpy((char *) menu->name,
1415 				effects_control[menu->index],
1416 				sizeof menu->name);
1417 			return 0;
1418 		}
1419 		break;
1420 	}
1421 	return -EINVAL;
1422 }
1423 
1424 /* sub-driver description */
1425 static const struct sd_desc sd_desc = {
1426 	.name = MODULE_NAME,
1427 	.ctrls = sd_ctrls,
1428 	.nctrls = ARRAY_SIZE(sd_ctrls),
1429 	.config = sd_config,
1430 	.init = sd_init,
1431 	.start = sd_start,
1432 	.stopN = sd_stopN,
1433 	.pkt_scan = sd_pkt_scan,
1434 	.querymenu = sd_querymenu,
1435 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1436 	.other_input = 1,
1437 #endif
1438 };
1439 
1440 /* -- module initialisation -- */
1441 static const struct usb_device_id device_table[] = {
1442 	{USB_DEVICE(0x17a1, 0x0128)},
1443 	{}
1444 };
1445 MODULE_DEVICE_TABLE(usb, device_table);
1446 
1447 /* -- device connect -- */
sd_probe(struct usb_interface * intf,const struct usb_device_id * id)1448 static int sd_probe(struct usb_interface *intf,
1449 		    const struct usb_device_id *id)
1450 {
1451 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1452 			       THIS_MODULE);
1453 }
1454 
1455 static struct usb_driver sd_driver = {
1456 	.name = MODULE_NAME,
1457 	.id_table = device_table,
1458 	.probe = sd_probe,
1459 	.disconnect = gspca_disconnect,
1460 #ifdef CONFIG_PM
1461 	.suspend = gspca_suspend,
1462 	.resume = gspca_resume,
1463 #endif
1464 };
1465 
1466 module_usb_driver(sd_driver);
1467