• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  *Notes: * t613  + tas5130A
19  *	* Focus to light do not balance well as in win.
20  *	  Quality in win is not good, but its kinda better.
21  *	 * Fix some "extraneous bytes", most of apps will show the image anyway
22  *	 * Gamma table, is there, but its really doing something?
23  *	 * 7~8 Fps, its ok, max on win its 10.
24  *			Costantino Leandro
25  */
26 
27 #define MODULE_NAME "t613"
28 
29 #include "gspca.h"
30 
31 #define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0)
32 
33 MODULE_AUTHOR("Leandro Costantino <le_costantino@pixartargentina.com.ar>");
34 MODULE_DESCRIPTION("GSPCA/T613 (JPEG Compliance) USB Camera Driver");
35 MODULE_LICENSE("GPL");
36 
37 struct sd {
38 	struct gspca_dev gspca_dev;	/* !! must be the first item */
39 
40 	unsigned char brightness;
41 	unsigned char contrast;
42 	unsigned char colors;
43 	unsigned char autogain;
44 	unsigned char gamma;
45 	unsigned char sharpness;
46 	unsigned char freq;
47 	unsigned char whitebalance;
48 	unsigned char mirror;
49 	unsigned char effect;
50 
51 	__u8 sensor;
52 #define SENSOR_TAS5130A 0
53 #define SENSOR_OM6802 1
54 };
55 
56 /* V4L2 controls supported by the driver */
57 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
58 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
59 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
60 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
61 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
62 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
63 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val);
64 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val);
65 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
66 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
67 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
68 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
69 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
70 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
71 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val);
72 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val);
73 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val);
74 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val);
75 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val);
76 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
77 static int sd_querymenu(struct gspca_dev *gspca_dev,
78 			struct v4l2_querymenu *menu);
79 
80 static struct ctrl sd_ctrls[] = {
81 #define SD_BRIGHTNESS 0
82 	{
83 	 {
84 	  .id = V4L2_CID_BRIGHTNESS,
85 	  .type = V4L2_CTRL_TYPE_INTEGER,
86 	  .name = "Brightness",
87 	  .minimum = 0,
88 	  .maximum = 14,
89 	  .step = 1,
90 	  .default_value = 8,
91 	  },
92 	 .set = sd_setbrightness,
93 	 .get = sd_getbrightness,
94 	 },
95 #define SD_CONTRAST 1
96 	{
97 	 {
98 	  .id = V4L2_CID_CONTRAST,
99 	  .type = V4L2_CTRL_TYPE_INTEGER,
100 	  .name = "Contrast",
101 	  .minimum = 0,
102 	  .maximum = 0x0d,
103 	  .step = 1,
104 	  .default_value = 0x07,
105 	  },
106 	 .set = sd_setcontrast,
107 	 .get = sd_getcontrast,
108 	 },
109 #define SD_COLOR 2
110 	{
111 	 {
112 	  .id = V4L2_CID_SATURATION,
113 	  .type = V4L2_CTRL_TYPE_INTEGER,
114 	  .name = "Color",
115 	  .minimum = 0,
116 	  .maximum = 0x0f,
117 	  .step = 1,
118 	  .default_value = 0x05,
119 	  },
120 	 .set = sd_setcolors,
121 	 .get = sd_getcolors,
122 	 },
123 #define GAMMA_MAX 16
124 #define GAMMA_DEF 10
125 	{
126 	 {
127 	  .id = V4L2_CID_GAMMA,	/* (gamma on win) */
128 	  .type = V4L2_CTRL_TYPE_INTEGER,
129 	  .name = "Gamma",
130 	  .minimum = 0,
131 	  .maximum = GAMMA_MAX - 1,
132 	  .step = 1,
133 	  .default_value = GAMMA_DEF,
134 	  },
135 	 .set = sd_setgamma,
136 	 .get = sd_getgamma,
137 	 },
138 #define SD_AUTOGAIN 4
139 	{
140 	 {
141 	  .id = V4L2_CID_GAIN,	/* here, i activate only the lowlight,
142 				 * some apps dont bring up the
143 				 * backligth_compensation control) */
144 	  .type = V4L2_CTRL_TYPE_INTEGER,
145 	  .name = "Low Light",
146 	  .minimum = 0,
147 	  .maximum = 1,
148 	  .step = 1,
149 	  .default_value = 0x01,
150 	  },
151 	 .set = sd_setlowlight,
152 	 .get = sd_getlowlight,
153 	 },
154 #define SD_MIRROR 5
155 	{
156 	 {
157 	  .id = V4L2_CID_HFLIP,
158 	  .type = V4L2_CTRL_TYPE_BOOLEAN,
159 	  .name = "Mirror Image",
160 	  .minimum = 0,
161 	  .maximum = 1,
162 	  .step = 1,
163 	  .default_value = 0,
164 	  },
165 	 .set = sd_setflip,
166 	 .get = sd_getflip
167 	},
168 #define SD_LIGHTFREQ 6
169 	{
170 	 {
171 	  .id = V4L2_CID_POWER_LINE_FREQUENCY,
172 	  .type = V4L2_CTRL_TYPE_MENU,
173 	  .name = "Light Frequency Filter",
174 	  .minimum = 1,		/* 1 -> 0x50, 2->0x60 */
175 	  .maximum = 2,
176 	  .step = 1,
177 	  .default_value = 1,
178 	  },
179 	 .set = sd_setfreq,
180 	 .get = sd_getfreq},
181 
182 #define SD_WHITE_BALANCE 7
183 	{
184 	 {
185 	  .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
186 	  .type = V4L2_CTRL_TYPE_INTEGER,
187 	  .name = "White Balance",
188 	  .minimum = 0,
189 	  .maximum = 1,
190 	  .step = 1,
191 	  .default_value = 0,
192 	  },
193 	 .set = sd_setwhitebalance,
194 	 .get = sd_getwhitebalance
195 	},
196 #define SD_SHARPNESS 8		/* (aka definition on win) */
197 	{
198 	 {
199 	  .id = V4L2_CID_SHARPNESS,
200 	  .type = V4L2_CTRL_TYPE_INTEGER,
201 	  .name = "Sharpness",
202 	  .minimum = 0,
203 	  .maximum = 15,
204 	  .step = 1,
205 	  .default_value = 0x06,
206 	  },
207 	 .set = sd_setsharpness,
208 	 .get = sd_getsharpness,
209 	 },
210 #define SD_EFFECTS 9
211 	{
212 	 {
213 	  .id = V4L2_CID_EFFECTS,
214 	  .type = V4L2_CTRL_TYPE_MENU,
215 	  .name = "Webcam Effects",
216 	  .minimum = 0,
217 	  .maximum = 4,
218 	  .step = 1,
219 	  .default_value = 0,
220 	  },
221 	 .set = sd_seteffect,
222 	 .get = sd_geteffect
223 	},
224 };
225 
226 static char *effects_control[] = {
227 	"Normal",
228 	"Emboss",		/* disabled */
229 	"Monochrome",
230 	"Sepia",
231 	"Sketch",
232 	"Sun Effect",		/* disabled */
233 	"Negative",
234 };
235 
236 static const struct v4l2_pix_format vga_mode_t16[] = {
237 	{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
238 		.bytesperline = 160,
239 		.sizeimage = 160 * 120 * 4 / 8 + 590,
240 		.colorspace = V4L2_COLORSPACE_JPEG,
241 		.priv = 4},
242 	{176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
243 		.bytesperline = 176,
244 		.sizeimage = 176 * 144 * 3 / 8 + 590,
245 		.colorspace = V4L2_COLORSPACE_JPEG,
246 		.priv = 3},
247 	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
248 		.bytesperline = 320,
249 		.sizeimage = 320 * 240 * 3 / 8 + 590,
250 		.colorspace = V4L2_COLORSPACE_JPEG,
251 		.priv = 2},
252 	{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
253 		.bytesperline = 352,
254 		.sizeimage = 352 * 288 * 3 / 8 + 590,
255 		.colorspace = V4L2_COLORSPACE_JPEG,
256 		.priv = 1},
257 	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
258 		.bytesperline = 640,
259 		.sizeimage = 640 * 480 * 3 / 8 + 590,
260 		.colorspace = V4L2_COLORSPACE_JPEG,
261 		.priv = 0},
262 };
263 
264 /* sensor specific data */
265 struct additional_sensor_data {
266 	const __u8 data1[20];
267 	const __u8 data2[18];
268 	const __u8 data3[18];
269 	const __u8 data4[4];
270 	const __u8 data5[6];
271 	const __u8 stream[4];
272 };
273 
274 const static struct additional_sensor_data sensor_data[] = {
275     {				/* TAS5130A */
276 	.data1 =
277 		{0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10,
278 		 0xd4, 0xbb, 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
279 		 0xd8, 0xc8, 0xd9, 0xfc},
280 	.data2 =
281 		{0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60,
282 		 0xe4, 0xa8, 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
283 		 0xe8, 0xe0},
284 	.data3 =
285 		{0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60,
286 		 0xcb, 0xa8, 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
287 		 0xcf, 0xe0},
288 	.data4 =	/* Freq (50/60Hz). Splitted for test purpose */
289 		{0x66, 0x00, 0xa8, 0xe8},
290 	.data5 =
291 		{0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
292 	.stream =
293 		{0x0b, 0x04, 0x0a, 0x40},
294     },
295     {				/* OM6802 */
296 	.data1 =
297 		{0xd0, 0xc2, 0xd1, 0x28, 0xd2, 0x0f, 0xd3, 0x22,
298 		 0xd4, 0xcd, 0xd5, 0x27, 0xd6, 0x2c, 0xd7, 0x06,
299 		 0xd8, 0xb3, 0xd9, 0xfc},
300 	.data2 =
301 		{0xe0, 0x80, 0xe1, 0xff, 0xe2, 0xff, 0xe3, 0x80,
302 		 0xe4, 0xff, 0xe5, 0xff, 0xe6, 0x80, 0xe7, 0xff,
303 		 0xe8, 0xff},
304 	.data3 =
305 		{0xc7, 0x80, 0xc8, 0xff, 0xc9, 0xff, 0xca, 0x80,
306 		 0xcb, 0xff, 0xcc, 0xff, 0xcd, 0x80, 0xce, 0xff,
307 		 0xcf, 0xff},
308 	.data4 =	/*Freq (50/60Hz). Splitted for test purpose */
309 		{0x66, 0xca, 0xa8, 0xf0 },
310 	.data5 =	/* this could be removed later */
311 		{0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
312 	.stream =
313 		{0x0b, 0x04, 0x0a, 0x78},
314     }
315 };
316 
317 #define MAX_EFFECTS 7
318 /* easily done by soft, this table could be removed,
319  * i keep it here just in case */
320 static const __u8 effects_table[MAX_EFFECTS][6] = {
321 	{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00},	/* Normal */
322 	{0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04},	/* Repujar */
323 	{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20},	/* Monochrome */
324 	{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x80},	/* Sepia */
325 	{0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x02},	/* Croquis */
326 	{0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x10},	/* Sun Effect */
327 	{0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40},	/* Negative */
328 };
329 
330 static const __u8 gamma_table[GAMMA_MAX][34] = {
331 	{0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85,	/* 0 */
332 	 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9,
333 	 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb,
334 	 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8,
335 	 0xa0, 0xff},
336 	{0x90, 0x00, 0x91, 0x33, 0x92, 0x5a, 0x93, 0x75,	/* 1 */
337 	 0x94, 0x85, 0x95, 0x93, 0x96, 0xa1, 0x97, 0xad,
338 	 0x98, 0xb7, 0x99, 0xc2, 0x9a, 0xcb, 0x9b, 0xd4,
339 	 0x9c, 0xde, 0x9D, 0xe7, 0x9e, 0xf0, 0x9f, 0xf7,
340 	 0xa0, 0xff},
341 	{0x90, 0x00, 0x91, 0x2f, 0x92, 0x51, 0x93, 0x6b,	/* 2 */
342 	 0x94, 0x7c, 0x95, 0x8a, 0x96, 0x99, 0x97, 0xa6,
343 	 0x98, 0xb1, 0x99, 0xbc, 0x9a, 0xc6, 0x9b, 0xd0,
344 	 0x9c, 0xdb, 0x9d, 0xe4, 0x9e, 0xed, 0x9f, 0xf6,
345 	 0xa0, 0xff},
346 	{0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60,	/* 3 */
347 	 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9e,
348 	 0x98, 0xaa, 0x99, 0xb5, 0x9a, 0xbf, 0x9b, 0xcb,
349 	 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
350 	 0xa0, 0xff},
351 	{0x90, 0x00, 0x91, 0x23, 0x92, 0x3f, 0x93, 0x55,	/* 4 */
352 	 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95,
353 	 0x98, 0xa2, 0x99, 0xad, 0x9a, 0xb9, 0x9b, 0xc6,
354 	 0x9c, 0xd2, 0x9d, 0xde, 0x9e, 0xe9, 0x9f, 0xf4,
355 	 0xa0, 0xff},
356 	{0x90, 0x00, 0x91, 0x1b, 0x92, 0x33, 0x93, 0x48,	/* 5 */
357 	 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87,
358 	 0x98, 0x96, 0x99, 0xa3, 0x9a, 0xb1, 0x9b, 0xbe,
359 	 0x9c, 0xcc, 0x9d, 0xda, 0x9e, 0xe7, 0x9f, 0xf3,
360 	 0xa0, 0xff},
361 	{0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20,	/* 6 */
362 	 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67,
363 	 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa,
364 	 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee,
365 	 0xa0, 0xff},
366 	{0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26,	/* 7 */
367 	 0x94, 0x38, 0x95, 0x4a, 0x96, 0x60, 0x97, 0x70,
368 	 0x98, 0x80, 0x99, 0x90, 0x9a, 0xa0, 0x9b, 0xb0,
369 	 0x9c, 0xc0, 0x9D, 0xd0, 0x9e, 0xe0, 0x9f, 0xf0,
370 	 0xa0, 0xff},
371 	{0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35,	/* 8 */
372 	 0x94, 0x47, 0x95, 0x5a, 0x96, 0x69, 0x97, 0x79,
373 	 0x98, 0x88, 0x99, 0x97, 0x9a, 0xa7, 0x9b, 0xb6,
374 	 0x9c, 0xc4, 0x9d, 0xd3, 0x9e, 0xe0, 0x9f, 0xf0,
375 	 0xa0, 0xff},
376 	{0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40,	/* 9 */
377 	 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
378 	 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd,
379 	 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0,
380 	 0xa0, 0xff},
381 	{0x90, 0x00, 0x91, 0x18, 0x92, 0x2b, 0x93, 0x44,	/* 10 */
382 	 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8e,
383 	 0x98, 0x9c, 0x99, 0xaa, 0x9a, 0xb7, 0x9b, 0xc4,
384 	 0x9c, 0xd0, 0x9d, 0xd8, 0x9e, 0xe2, 0x9f, 0xf0,
385 	 0xa0, 0xff},
386 	{0x90, 0x00, 0x91, 0x1a, 0x92, 0x34, 0x93, 0x52,	/* 11 */
387 	 0x94, 0x66, 0x95, 0x7e, 0x96, 0x8D, 0x97, 0x9B,
388 	 0x98, 0xa8, 0x99, 0xb4, 0x9a, 0xc0, 0x9b, 0xcb,
389 	 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
390 	 0xa0, 0xff},
391 	{0x90, 0x00, 0x91, 0x3f, 0x92, 0x5a, 0x93, 0x6e,	/* 12 */
392 	 0x94, 0x7f, 0x95, 0x8e, 0x96, 0x9c, 0x97, 0xa8,
393 	 0x98, 0xb4, 0x99, 0xbf, 0x9a, 0xc9, 0x9b, 0xd3,
394 	 0x9c, 0xdc, 0x9d, 0xe5, 0x9e, 0xee, 0x9f, 0xf6,
395 	 0xa0, 0xff},
396 	{0x90, 0x00, 0x91, 0x54, 0x92, 0x6f, 0x93, 0x83,	/* 13 */
397 	 0x94, 0x93, 0x95, 0xa0, 0x96, 0xad, 0x97, 0xb7,
398 	 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdc,
399 	 0x9c, 0xe4, 0x9d, 0xeb, 0x9e, 0xf2, 0x9f, 0xf9,
400 	 0xa0, 0xff},
401 	{0x90, 0x00, 0x91, 0x6e, 0x92, 0x88, 0x93, 0x9a,	/* 14 */
402 	 0x94, 0xa8, 0x95, 0xb3, 0x96, 0xbd, 0x97, 0xc6,
403 	 0x98, 0xcf, 0x99, 0xd6, 0x9a, 0xdd, 0x9b, 0xe3,
404 	 0x9c, 0xe9, 0x9d, 0xef, 0x9e, 0xf4, 0x9f, 0xfa,
405 	 0xa0, 0xff},
406 	{0x90, 0x00, 0x91, 0x93, 0x92, 0xa8, 0x93, 0xb7,	/* 15 */
407 	 0x94, 0xc1, 0x95, 0xca, 0x96, 0xd2, 0x97, 0xd8,
408 	 0x98, 0xde, 0x99, 0xe3, 0x9a, 0xe8, 0x9b, 0xed,
409 	 0x9c, 0xf1, 0x9d, 0xf5, 0x9e, 0xf8, 0x9f, 0xfc,
410 	 0xa0, 0xff}
411 };
412 
413 static const __u8 tas5130a_sensor_init[][8] = {
414 	{0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
415 	{0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
416 	{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
417 	{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
418 	{},
419 };
420 
421 static __u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
422 
423 /* read 1 byte */
reg_r(struct gspca_dev * gspca_dev,__u16 index)424 static int reg_r(struct gspca_dev *gspca_dev,
425 		   __u16 index)
426 {
427 	usb_control_msg(gspca_dev->dev,
428 			usb_rcvctrlpipe(gspca_dev->dev, 0),
429 			0,		/* request */
430 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
431 			0,		/* value */
432 			index,
433 			gspca_dev->usb_buf, 1, 500);
434 	return gspca_dev->usb_buf[0];
435 }
436 
reg_w(struct gspca_dev * gspca_dev,__u16 index)437 static void reg_w(struct gspca_dev *gspca_dev,
438 		  __u16 index)
439 {
440 	usb_control_msg(gspca_dev->dev,
441 			usb_sndctrlpipe(gspca_dev->dev, 0),
442 			0,
443 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
444 			0, index,
445 			NULL, 0, 500);
446 }
447 
reg_w_buf(struct gspca_dev * gspca_dev,const __u8 * buffer,__u16 len)448 static void reg_w_buf(struct gspca_dev *gspca_dev,
449 		  const __u8 *buffer, __u16 len)
450 {
451 	if (len <= USB_BUF_SZ) {
452 		memcpy(gspca_dev->usb_buf, buffer, len);
453 		usb_control_msg(gspca_dev->dev,
454 				usb_sndctrlpipe(gspca_dev->dev, 0),
455 				0,
456 			   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
457 				0x01, 0,
458 				gspca_dev->usb_buf, len, 500);
459 	} else {
460 		__u8 *tmpbuf;
461 
462 		tmpbuf = kmalloc(len, GFP_KERNEL);
463 		memcpy(tmpbuf, buffer, len);
464 		usb_control_msg(gspca_dev->dev,
465 				usb_sndctrlpipe(gspca_dev->dev, 0),
466 				0,
467 			   USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
468 				0x01, 0,
469 				tmpbuf, len, 500);
470 		kfree(tmpbuf);
471 	}
472 }
473 
474 /* Reported as OM6802*/
om6802_sensor_init(struct gspca_dev * gspca_dev)475 static void om6802_sensor_init(struct gspca_dev *gspca_dev)
476 {
477 	int i;
478 	const __u8 *p;
479 	__u8 byte;
480 	__u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
481 	static const __u8 sensor_init[] = {
482 		0xdf, 0x6d,
483 		0xdd, 0x18,
484 		0x5a, 0xe0,
485 		0x5c, 0x07,
486 		0x5d, 0xb0,
487 		0x5e, 0x1e,
488 		0x60, 0x71,
489 		0xef, 0x00,
490 		0xe9, 0x00,
491 		0xea, 0x00,
492 		0x90, 0x24,
493 		0x91, 0xb2,
494 		0x82, 0x32,
495 		0xfd, 0x41,
496 		0x00			/* table end */
497 	};
498 
499 	reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
500 	msleep(5);
501 	i = 4;
502 	while (--i > 0) {
503 		byte = reg_r(gspca_dev, 0x0060);
504 		if (!(byte & 0x01))
505 			break;
506 		msleep(100);
507 	}
508 	byte = reg_r(gspca_dev, 0x0063);
509 	if (byte != 0x17) {
510 		err("Bad sensor reset %02x", byte);
511 		/* continue? */
512 	}
513 
514 	p = sensor_init;
515 	while (*p != 0) {
516 		val[1] = *p++;
517 		val[3] = *p++;
518 		if (*p == 0)
519 			reg_w(gspca_dev, 0x3c80);
520 		reg_w_buf(gspca_dev, val, sizeof val);
521 		i = 4;
522 		while (--i >= 0) {
523 			msleep(15);
524 			byte = reg_r(gspca_dev, 0x60);
525 			if (!(byte & 0x01))
526 				break;
527 		}
528 	}
529 	msleep(15);
530 	reg_w(gspca_dev, 0x3c80);
531 }
532 
533 /* this function is called at probe time */
sd_config(struct gspca_dev * gspca_dev,const struct usb_device_id * id)534 static int sd_config(struct gspca_dev *gspca_dev,
535 		     const struct usb_device_id *id)
536 {
537 	struct sd *sd = (struct sd *) gspca_dev;
538 	struct cam *cam;
539 
540 	cam = &gspca_dev->cam;
541 	cam->epaddr = 0x01;
542 
543 	cam->cam_mode = vga_mode_t16;
544 	cam->nmodes = ARRAY_SIZE(vga_mode_t16);
545 
546 	sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
547 	sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
548 	sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
549 	sd->gamma = GAMMA_DEF;
550 	sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
551 	sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
552 	sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
553 	sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
554 	sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value;
555 	return 0;
556 }
557 
setbrightness(struct gspca_dev * gspca_dev)558 static void setbrightness(struct gspca_dev *gspca_dev)
559 {
560 	struct sd *sd = (struct sd *) gspca_dev;
561 	unsigned int brightness;
562 	__u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
563 
564 	brightness = sd->brightness;
565 	if (brightness < 7) {
566 		set6[1] = 0x26;
567 		set6[3] = 0x70 - brightness * 0x10;
568 	} else {
569 		set6[3] = 0x00 + ((brightness - 7) * 0x10);
570 	}
571 
572 	reg_w_buf(gspca_dev, set6, sizeof set6);
573 }
574 
setcontrast(struct gspca_dev * gspca_dev)575 static void setcontrast(struct gspca_dev *gspca_dev)
576 {
577 	struct sd *sd = (struct sd *) gspca_dev;
578 	unsigned int contrast = sd->contrast;
579 	__u16 reg_to_write;
580 
581 	if (contrast < 7)
582 		reg_to_write = 0x8ea9 - contrast * 0x200;
583 	else
584 		reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
585 
586 	reg_w(gspca_dev, reg_to_write);
587 }
588 
setcolors(struct gspca_dev * gspca_dev)589 static void setcolors(struct gspca_dev *gspca_dev)
590 {
591 	struct sd *sd = (struct sd *) gspca_dev;
592 	__u16 reg_to_write;
593 
594 	reg_to_write = 0x80bb + sd->colors * 0x100;	/* was 0xc0 */
595 	reg_w(gspca_dev, reg_to_write);
596 }
597 
setgamma(struct gspca_dev * gspca_dev)598 static void setgamma(struct gspca_dev *gspca_dev)
599 {
600 	struct sd *sd = (struct sd *) gspca_dev;
601 
602 	PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
603 	reg_w_buf(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]);
604 }
605 
setwhitebalance(struct gspca_dev * gspca_dev)606 static void setwhitebalance(struct gspca_dev *gspca_dev)
607 {
608 	struct sd *sd = (struct sd *) gspca_dev;
609 
610 	__u8 white_balance[8] =
611 		{0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38};
612 
613 	if (sd->whitebalance)
614 		white_balance[7] = 0x3c;
615 
616 	reg_w_buf(gspca_dev, white_balance, sizeof white_balance);
617 }
618 
setsharpness(struct gspca_dev * gspca_dev)619 static void setsharpness(struct gspca_dev *gspca_dev)
620 {
621 	struct sd *sd = (struct sd *) gspca_dev;
622 	__u16 reg_to_write;
623 
624 	reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
625 
626 	reg_w(gspca_dev, reg_to_write);
627 }
628 
629 /* this function is called at probe and resume time */
sd_init(struct gspca_dev * gspca_dev)630 static int sd_init(struct gspca_dev *gspca_dev)
631 {
632 	/* some of this registers are not really neded, because
633 	 * they are overriden by setbrigthness, setcontrast, etc,
634 	 * but wont hurt anyway, and can help someone with similar webcam
635 	 * to see the initial parameters.*/
636 	struct sd *sd = (struct sd *) gspca_dev;
637 	int i;
638 	__u8 byte, test_byte;
639 
640 	static const __u8 read_indexs[] =
641 		{ 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
642 		  0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
643 	static const __u8 n1[] =
644 			{0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
645 	static const __u8 n2[] =
646 			{0x08, 0x00};
647 	static const __u8 n3[] =
648 			{0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
649 	static const __u8 n4[] =
650 		{0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
651 		 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
652 		 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
653 		 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
654 		 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
655 		 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
656 		 0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
657 		 0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
658 		 0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
659 	static const __u8 nset9[4] =
660 			{ 0x0b, 0x04, 0x0a, 0x78 };
661 	static const __u8 nset8[6] =
662 			{ 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
663 
664 	byte = reg_r(gspca_dev, 0x06);
665 	test_byte = reg_r(gspca_dev, 0x07);
666 	if (byte == 0x08 && test_byte == 0x07) {
667 		PDEBUG(D_CONF, "sensor om6802");
668 		sd->sensor = SENSOR_OM6802;
669 	} else if (byte == 0x08 && test_byte == 0x01) {
670 		PDEBUG(D_CONF, "sensor tas5130a");
671 		sd->sensor = SENSOR_TAS5130A;
672 	} else {
673 		PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte);
674 		sd->sensor = SENSOR_TAS5130A;
675 	}
676 
677 	reg_w_buf(gspca_dev, n1, sizeof n1);
678 	test_byte = 0;
679 	i = 5;
680 	while (--i >= 0) {
681 		reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
682 		test_byte = reg_r(gspca_dev, 0x0063);
683 		msleep(100);
684 		if (test_byte == 0x17)
685 			break;		/* OK */
686 	}
687 	if (i < 0) {
688 		err("Bad sensor reset %02x", test_byte);
689 /*		return -EIO; */
690 /*fixme: test - continue */
691 	}
692 	reg_w_buf(gspca_dev, n2, sizeof n2);
693 
694 	i = 0;
695 	while (read_indexs[i] != 0x00) {
696 		test_byte = reg_r(gspca_dev, read_indexs[i]);
697 		PDEBUG(D_STREAM, "Reg 0x%02x = 0x%02x", read_indexs[i],
698 		       test_byte);
699 		i++;
700 	}
701 
702 	reg_w_buf(gspca_dev, n3, sizeof n3);
703 	reg_w_buf(gspca_dev, n4, sizeof n4);
704 	reg_r(gspca_dev, 0x0080);
705 	reg_w(gspca_dev, 0x2c80);
706 
707 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
708 			sizeof sensor_data[sd->sensor].data1);
709 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
710 			sizeof sensor_data[sd->sensor].data3);
711 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
712 			sizeof sensor_data[sd->sensor].data2);
713 
714 	reg_w(gspca_dev, 0x3880);
715 	reg_w(gspca_dev, 0x3880);
716 	reg_w(gspca_dev, 0x338e);
717 
718 	setbrightness(gspca_dev);
719 	setcontrast(gspca_dev);
720 	setgamma(gspca_dev);
721 	setcolors(gspca_dev);
722 	setsharpness(gspca_dev);
723 	setwhitebalance(gspca_dev);
724 
725 	reg_w(gspca_dev, 0x2087);	/* tied to white balance? */
726 	reg_w(gspca_dev, 0x2088);
727 	reg_w(gspca_dev, 0x2089);
728 
729 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
730 			sizeof sensor_data[sd->sensor].data4);
731 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5,
732 			sizeof sensor_data[sd->sensor].data5);
733 	reg_w_buf(gspca_dev, nset8, sizeof nset8);
734 	reg_w_buf(gspca_dev, nset9, sizeof nset9);
735 
736 	reg_w(gspca_dev, 0x2880);
737 
738 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
739 			sizeof sensor_data[sd->sensor].data1);
740 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
741 			sizeof sensor_data[sd->sensor].data3);
742 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
743 			sizeof sensor_data[sd->sensor].data2);
744 
745 	return 0;
746 }
747 
setflip(struct gspca_dev * gspca_dev)748 static void setflip(struct gspca_dev *gspca_dev)
749 {
750 	struct sd *sd = (struct sd *) gspca_dev;
751 	__u8 flipcmd[8] =
752 		{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
753 
754 	if (sd->mirror)
755 		flipcmd[3] = 0x01;
756 
757 	reg_w_buf(gspca_dev, flipcmd, sizeof flipcmd);
758 }
759 
seteffect(struct gspca_dev * gspca_dev)760 static void seteffect(struct gspca_dev *gspca_dev)
761 {
762 	struct sd *sd = (struct sd *) gspca_dev;
763 
764 	reg_w_buf(gspca_dev, effects_table[sd->effect],
765 				sizeof effects_table[0]);
766 	if (sd->effect == 1 || sd->effect == 5) {
767 		PDEBUG(D_CONF,
768 		       "This effect have been disabled for webcam \"safety\"");
769 		return;
770 	}
771 
772 	if (sd->effect == 1 || sd->effect == 4)
773 		reg_w(gspca_dev, 0x4aa6);
774 	else
775 		reg_w(gspca_dev, 0xfaa6);
776 }
777 
setlightfreq(struct gspca_dev * gspca_dev)778 static void setlightfreq(struct gspca_dev *gspca_dev)
779 {
780 	struct sd *sd = (struct sd *) gspca_dev;
781 	__u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
782 
783 	if (sd->freq == 2)	/* 60hz */
784 		freq[1] = 0x00;
785 
786 	reg_w_buf(gspca_dev, freq, sizeof freq);
787 }
788 
789 /* Is this really needed?
790  * i added some module parameters for test with some users */
poll_sensor(struct gspca_dev * gspca_dev)791 static void poll_sensor(struct gspca_dev *gspca_dev)
792 {
793 	struct sd *sd = (struct sd *) gspca_dev;
794 	static const __u8 poll1[] =
795 		{0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
796 		 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
797 		 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
798 		 0x60, 0x14};
799 	static const __u8 poll2[] =
800 		{0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
801 		 0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
802 	static const __u8 poll3[] =
803 		{0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d};
804 	static const __u8 poll4[] =
805 		{0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
806 		 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
807 		 0xc2, 0x80, 0xc3, 0x10};
808 
809 	if (sd->sensor != SENSOR_TAS5130A) {
810 		PDEBUG(D_STREAM, "[Sensor requires polling]");
811 		reg_w_buf(gspca_dev, poll1, sizeof poll1);
812 		reg_w_buf(gspca_dev, poll2, sizeof poll2);
813 		reg_w_buf(gspca_dev, poll3, sizeof poll3);
814 		reg_w_buf(gspca_dev, poll4, sizeof poll4);
815 	}
816 }
817 
sd_start(struct gspca_dev * gspca_dev)818 static int sd_start(struct gspca_dev *gspca_dev)
819 {
820 	struct sd *sd = (struct sd *) gspca_dev;
821 	int i, mode;
822 	__u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
823 	static const __u8 t3[] =
824 		{ 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
825 		  0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
826 
827 	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
828 	switch (mode) {
829 	case 1:		/* 352x288 */
830 		t2[1] = 0x40;
831 		break;
832 	case 2:		/* 320x240 */
833 		t2[1] = 0x10;
834 		break;
835 	case 3:		/* 176x144 */
836 		t2[1] = 0x50;
837 		break;
838 	case 4:		/* 160x120 */
839 		t2[1] = 0x20;
840 		break;
841 	default:	/* 640x480 (0x00) */
842 		break;
843 	}
844 
845 	if (sd->sensor == SENSOR_TAS5130A) {
846 		i = 0;
847 		while (tas5130a_sensor_init[i][0] != 0) {
848 			reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
849 					 sizeof tas5130a_sensor_init[0]);
850 			i++;
851 		}
852 		reg_w(gspca_dev, 0x3c80);
853 		/* just in case and to keep sync with logs (for mine) */
854 		reg_w_buf(gspca_dev, tas5130a_sensor_init[3],
855 				 sizeof tas5130a_sensor_init[0]);
856 		reg_w(gspca_dev, 0x3c80);
857 	} else {
858 		om6802_sensor_init(gspca_dev);
859 	}
860 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
861 			sizeof sensor_data[sd->sensor].data4);
862 	reg_r(gspca_dev, 0x0012);
863 	reg_w_buf(gspca_dev, t2, sizeof t2);
864 	reg_w_buf(gspca_dev, t3, sizeof t3);
865 	reg_w(gspca_dev, 0x0013);
866 	msleep(15);
867 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
868 			sizeof sensor_data[sd->sensor].stream);
869 	poll_sensor(gspca_dev);
870 
871 	/* restart on each start, just in case, sometimes regs goes wrong
872 	 * when using controls from app */
873 	setbrightness(gspca_dev);
874 	setcontrast(gspca_dev);
875 	setcolors(gspca_dev);
876 	return 0;
877 }
878 
sd_stopN(struct gspca_dev * gspca_dev)879 static void sd_stopN(struct gspca_dev *gspca_dev)
880 {
881 	struct sd *sd = (struct sd *) gspca_dev;
882 
883 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
884 			sizeof sensor_data[sd->sensor].stream);
885 	msleep(20);
886 	reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
887 			sizeof sensor_data[sd->sensor].stream);
888 	msleep(20);
889 	reg_w(gspca_dev, 0x0309);
890 }
891 
sd_pkt_scan(struct gspca_dev * gspca_dev,struct gspca_frame * frame,__u8 * data,int len)892 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
893 			struct gspca_frame *frame,	/* target */
894 			__u8 *data,			/* isoc packet */
895 			int len)			/* iso packet length */
896 {
897 	static __u8 ffd9[] = { 0xff, 0xd9 };
898 
899 	if (data[0] == 0x5a) {
900 		/* Control Packet, after this came the header again,
901 		 * but extra bytes came in the packet before this,
902 		 * sometimes an EOF arrives, sometimes not... */
903 		return;
904 	}
905 	data += 2;
906 	len -= 2;
907 	if (data[0] == 0xff && data[1] == 0xd8) {
908 		/* extra bytes....., could be processed too but would be
909 		 * a waste of time, right now leave the application and
910 		 * libjpeg do it for ourserlves.. */
911 		frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
912 					ffd9, 2);
913 		gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
914 		return;
915 	}
916 
917 	if (data[len - 2] == 0xff && data[len - 1] == 0xd9) {
918 		/* Just in case, i have seen packets with the marker,
919 		 * other's do not include it... */
920 		len -= 2;
921 	}
922 	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
923 }
924 
sd_setbrightness(struct gspca_dev * gspca_dev,__s32 val)925 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
926 {
927 	struct sd *sd = (struct sd *) gspca_dev;
928 
929 	sd->brightness = val;
930 	if (gspca_dev->streaming)
931 		setbrightness(gspca_dev);
932 	return 0;
933 }
934 
sd_getbrightness(struct gspca_dev * gspca_dev,__s32 * val)935 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
936 {
937 	struct sd *sd = (struct sd *) gspca_dev;
938 
939 	*val = sd->brightness;
940 	return *val;
941 }
942 
sd_setwhitebalance(struct gspca_dev * gspca_dev,__s32 val)943 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
944 {
945 	struct sd *sd = (struct sd *) gspca_dev;
946 
947 	sd->whitebalance = val;
948 	if (gspca_dev->streaming)
949 		setwhitebalance(gspca_dev);
950 	return 0;
951 }
952 
sd_getwhitebalance(struct gspca_dev * gspca_dev,__s32 * val)953 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
954 {
955 	struct sd *sd = (struct sd *) gspca_dev;
956 
957 	*val = sd->whitebalance;
958 	return *val;
959 }
960 
sd_setflip(struct gspca_dev * gspca_dev,__s32 val)961 static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
962 {
963 	struct sd *sd = (struct sd *) gspca_dev;
964 
965 	sd->mirror = val;
966 	if (gspca_dev->streaming)
967 		setflip(gspca_dev);
968 	return 0;
969 }
970 
sd_getflip(struct gspca_dev * gspca_dev,__s32 * val)971 static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
972 {
973 	struct sd *sd = (struct sd *) gspca_dev;
974 
975 	*val = sd->mirror;
976 	return *val;
977 }
978 
sd_seteffect(struct gspca_dev * gspca_dev,__s32 val)979 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val)
980 {
981 	struct sd *sd = (struct sd *) gspca_dev;
982 
983 	sd->effect = val;
984 	if (gspca_dev->streaming)
985 		seteffect(gspca_dev);
986 	return 0;
987 }
988 
sd_geteffect(struct gspca_dev * gspca_dev,__s32 * val)989 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val)
990 {
991 	struct sd *sd = (struct sd *) gspca_dev;
992 
993 	*val = sd->effect;
994 	return *val;
995 }
996 
sd_setcontrast(struct gspca_dev * gspca_dev,__s32 val)997 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
998 {
999 	struct sd *sd = (struct sd *) gspca_dev;
1000 
1001 	sd->contrast = val;
1002 	if (gspca_dev->streaming)
1003 		setcontrast(gspca_dev);
1004 	return 0;
1005 }
1006 
sd_getcontrast(struct gspca_dev * gspca_dev,__s32 * val)1007 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1008 {
1009 	struct sd *sd = (struct sd *) gspca_dev;
1010 
1011 	*val = sd->contrast;
1012 	return *val;
1013 }
1014 
sd_setcolors(struct gspca_dev * gspca_dev,__s32 val)1015 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1016 {
1017 	struct sd *sd = (struct sd *) gspca_dev;
1018 
1019 	sd->colors = val;
1020 	if (gspca_dev->streaming)
1021 		setcolors(gspca_dev);
1022 	return 0;
1023 }
1024 
sd_getcolors(struct gspca_dev * gspca_dev,__s32 * val)1025 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1026 {
1027 	struct sd *sd = (struct sd *) gspca_dev;
1028 
1029 	*val = sd->colors;
1030 	return 0;
1031 }
1032 
sd_setgamma(struct gspca_dev * gspca_dev,__s32 val)1033 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
1034 {
1035 	struct sd *sd = (struct sd *) gspca_dev;
1036 
1037 	sd->gamma = val;
1038 	if (gspca_dev->streaming)
1039 		setgamma(gspca_dev);
1040 	return 0;
1041 }
1042 
sd_getgamma(struct gspca_dev * gspca_dev,__s32 * val)1043 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
1044 {
1045 	struct sd *sd = (struct sd *) gspca_dev;
1046 
1047 	*val = sd->gamma;
1048 	return 0;
1049 }
1050 
sd_setfreq(struct gspca_dev * gspca_dev,__s32 val)1051 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1052 {
1053 	struct sd *sd = (struct sd *) gspca_dev;
1054 
1055 	sd->freq = val;
1056 	if (gspca_dev->streaming)
1057 		setlightfreq(gspca_dev);
1058 	return 0;
1059 }
1060 
sd_getfreq(struct gspca_dev * gspca_dev,__s32 * val)1061 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1062 {
1063 	struct sd *sd = (struct sd *) gspca_dev;
1064 
1065 	*val = sd->freq;
1066 	return 0;
1067 }
1068 
sd_setsharpness(struct gspca_dev * gspca_dev,__s32 val)1069 static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1070 {
1071 	struct sd *sd = (struct sd *) gspca_dev;
1072 
1073 	sd->sharpness = val;
1074 	if (gspca_dev->streaming)
1075 		setsharpness(gspca_dev);
1076 	return 0;
1077 }
1078 
sd_getsharpness(struct gspca_dev * gspca_dev,__s32 * val)1079 static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
1080 {
1081 	struct sd *sd = (struct sd *) gspca_dev;
1082 
1083 	*val = sd->sharpness;
1084 	return 0;
1085 }
1086 
1087 /* Low Light set  here......*/
sd_setlowlight(struct gspca_dev * gspca_dev,__s32 val)1088 static int sd_setlowlight(struct gspca_dev *gspca_dev, __s32 val)
1089 {
1090 	struct sd *sd = (struct sd *) gspca_dev;
1091 
1092 	sd->autogain = val;
1093 	if (val != 0)
1094 		reg_w(gspca_dev, 0xf48e);
1095 	else
1096 		reg_w(gspca_dev, 0xb48e);
1097 	return 0;
1098 }
1099 
sd_getlowlight(struct gspca_dev * gspca_dev,__s32 * val)1100 static int sd_getlowlight(struct gspca_dev *gspca_dev, __s32 *val)
1101 {
1102 	struct sd *sd = (struct sd *) gspca_dev;
1103 
1104 	*val = sd->autogain;
1105 	return 0;
1106 }
1107 
sd_querymenu(struct gspca_dev * gspca_dev,struct v4l2_querymenu * menu)1108 static int sd_querymenu(struct gspca_dev *gspca_dev,
1109 			struct v4l2_querymenu *menu)
1110 {
1111 	switch (menu->id) {
1112 	case V4L2_CID_POWER_LINE_FREQUENCY:
1113 		switch (menu->index) {
1114 		case 1:		/* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1115 			strcpy((char *) menu->name, "50 Hz");
1116 			return 0;
1117 		case 2:		/* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1118 			strcpy((char *) menu->name, "60 Hz");
1119 			return 0;
1120 		}
1121 		break;
1122 	case V4L2_CID_EFFECTS:
1123 		if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
1124 			strncpy((char *) menu->name,
1125 				effects_control[menu->index], 32);
1126 			return 0;
1127 		}
1128 		break;
1129 	}
1130 	return -EINVAL;
1131 }
1132 
1133 /* sub-driver description */
1134 static const struct sd_desc sd_desc = {
1135 	.name = MODULE_NAME,
1136 	.ctrls = sd_ctrls,
1137 	.nctrls = ARRAY_SIZE(sd_ctrls),
1138 	.config = sd_config,
1139 	.init = sd_init,
1140 	.start = sd_start,
1141 	.stopN = sd_stopN,
1142 	.pkt_scan = sd_pkt_scan,
1143 	.querymenu = sd_querymenu,
1144 };
1145 
1146 /* -- module initialisation -- */
1147 static const __devinitdata struct usb_device_id device_table[] = {
1148 	{USB_DEVICE(0x17a1, 0x0128)},
1149 	{}
1150 };
1151 MODULE_DEVICE_TABLE(usb, device_table);
1152 
1153 /* -- device connect -- */
sd_probe(struct usb_interface * intf,const struct usb_device_id * id)1154 static int sd_probe(struct usb_interface *intf,
1155 		    const struct usb_device_id *id)
1156 {
1157 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1158 			       THIS_MODULE);
1159 }
1160 
1161 static struct usb_driver sd_driver = {
1162 	.name = MODULE_NAME,
1163 	.id_table = device_table,
1164 	.probe = sd_probe,
1165 	.disconnect = gspca_disconnect,
1166 #ifdef CONFIG_PM
1167 	.suspend = gspca_suspend,
1168 	.resume = gspca_resume,
1169 #endif
1170 };
1171 
1172 /* -- module insert / remove -- */
sd_mod_init(void)1173 static int __init sd_mod_init(void)
1174 {
1175 	if (usb_register(&sd_driver) < 0)
1176 		return -1;
1177 	PDEBUG(D_PROBE, "registered");
1178 	return 0;
1179 }
sd_mod_exit(void)1180 static void __exit sd_mod_exit(void)
1181 {
1182 	usb_deregister(&sd_driver);
1183 	PDEBUG(D_PROBE, "deregistered");
1184 }
1185 
1186 module_init(sd_mod_init);
1187 module_exit(sd_mod_exit);
1188