1 /*
2  *		Pixart PAC7302 library
3  *		Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
4  *
5  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6  *
7  * Separated from Pixart PAC7311 library by Márton Németh
8  * Camera button input handling by Márton Németh <nm127@freemail.hu>
9  * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24  */
25 
26 /* Some documentation about various registers as determined by trial and error.
27 
28    Register page 1:
29 
30    Address	Description
31    0x78		Global control, bit 6 controls the LED (inverted)
32 
33    Register page 3:
34 
35    Address	Description
36    0x02		Clock divider 3-63, fps = 90 / val. Must be a multiple of 3 on
37 		the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
38    0x03		Variable framerate ctrl reg2==3: 0 -> ~30 fps, 255 -> ~22fps
39    0x04		Another var framerate ctrl reg2==3, reg3==0: 0 -> ~30 fps,
40 		63 -> ~27 fps, the 2 msb's must always be 1 !!
41    0x05		Another var framerate ctrl reg2==3, reg3==0, reg4==0xc0:
42 		1 -> ~30 fps, 2 -> ~20 fps
43    0x0e		Exposure bits 0-7, 0-448, 0 = use full frame time
44    0x0f		Exposure bit 8, 0-448, 448 = no exposure at all
45    0x10		Master gain 0-31
46    0x21		Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
47 
48    The registers are accessed in the following functions:
49 
50    Page | Register   | Function
51    -----+------------+---------------------------------------------------
52     0   | 0x0f..0x20 | setcolors()
53     0   | 0xa2..0xab | setbrightcont()
54     0   | 0xc5       | setredbalance()
55     0   | 0xc6       | setwhitebalance()
56     0   | 0xc7       | setbluebalance()
57     0   | 0xdc       | setbrightcont(), setcolors()
58     3   | 0x02       | setexposure()
59     3   | 0x10       | setgain()
60     3   | 0x11       | setcolors(), setgain(), setexposure(), sethvflip()
61     3   | 0x21       | sethvflip()
62 */
63 
64 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
65 
66 #define MODULE_NAME "pac7302"
67 
68 #include <linux/input.h>
69 #include <media/v4l2-chip-ident.h>
70 #include "gspca.h"
71 
72 MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
73 MODULE_DESCRIPTION("Pixart PAC7302");
74 MODULE_LICENSE("GPL");
75 
76 /* specific webcam descriptor for pac7302 */
77 struct sd {
78 	struct gspca_dev gspca_dev;		/* !! must be the first item */
79 
80 	unsigned char brightness;
81 	unsigned char contrast;
82 	unsigned char colors;
83 	unsigned char white_balance;
84 	unsigned char red_balance;
85 	unsigned char blue_balance;
86 	unsigned char gain;
87 	unsigned char autogain;
88 	unsigned short exposure;
89 	__u8 hflip;
90 	__u8 vflip;
91 	u8 flags;
92 #define FL_HFLIP 0x01		/* mirrored by default */
93 #define FL_VFLIP 0x02		/* vertical flipped by default */
94 
95 	u8 sof_read;
96 	u8 autogain_ignore_frames;
97 
98 	atomic_t avg_lum;
99 };
100 
101 /* V4L2 controls supported by the driver */
102 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
103 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
104 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
105 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
106 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
107 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
108 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val);
109 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val);
110 static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val);
111 static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val);
112 static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val);
113 static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val);
114 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
115 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
116 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
117 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
118 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
119 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
120 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
121 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
122 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
123 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
124 
125 static const struct ctrl sd_ctrls[] = {
126 	{
127 	    {
128 		.id      = V4L2_CID_BRIGHTNESS,
129 		.type    = V4L2_CTRL_TYPE_INTEGER,
130 		.name    = "Brightness",
131 		.minimum = 0,
132 #define BRIGHTNESS_MAX 0x20
133 		.maximum = BRIGHTNESS_MAX,
134 		.step    = 1,
135 #define BRIGHTNESS_DEF 0x10
136 		.default_value = BRIGHTNESS_DEF,
137 	    },
138 	    .set = sd_setbrightness,
139 	    .get = sd_getbrightness,
140 	},
141 	{
142 	    {
143 		.id      = V4L2_CID_CONTRAST,
144 		.type    = V4L2_CTRL_TYPE_INTEGER,
145 		.name    = "Contrast",
146 		.minimum = 0,
147 #define CONTRAST_MAX 255
148 		.maximum = CONTRAST_MAX,
149 		.step    = 1,
150 #define CONTRAST_DEF 127
151 		.default_value = CONTRAST_DEF,
152 	    },
153 	    .set = sd_setcontrast,
154 	    .get = sd_getcontrast,
155 	},
156 	{
157 	    {
158 		.id      = V4L2_CID_SATURATION,
159 		.type    = V4L2_CTRL_TYPE_INTEGER,
160 		.name    = "Saturation",
161 		.minimum = 0,
162 #define COLOR_MAX 255
163 		.maximum = COLOR_MAX,
164 		.step    = 1,
165 #define COLOR_DEF 127
166 		.default_value = COLOR_DEF,
167 	    },
168 	    .set = sd_setcolors,
169 	    .get = sd_getcolors,
170 	},
171 	{
172 	    {
173 		.id      = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
174 		.type    = V4L2_CTRL_TYPE_INTEGER,
175 		.name    = "White Balance",
176 		.minimum = 0,
177 		.maximum = 255,
178 		.step    = 1,
179 #define WHITEBALANCE_DEF 4
180 		.default_value = WHITEBALANCE_DEF,
181 	    },
182 	    .set = sd_setwhitebalance,
183 	    .get = sd_getwhitebalance,
184 	},
185 	{
186 	    {
187 		.id      = V4L2_CID_RED_BALANCE,
188 		.type    = V4L2_CTRL_TYPE_INTEGER,
189 		.name    = "Red",
190 		.minimum = 0,
191 		.maximum = 3,
192 		.step    = 1,
193 #define REDBALANCE_DEF 1
194 		.default_value = REDBALANCE_DEF,
195 	    },
196 	    .set = sd_setredbalance,
197 	    .get = sd_getredbalance,
198 	},
199 	{
200 	    {
201 		.id      = V4L2_CID_BLUE_BALANCE,
202 		.type    = V4L2_CTRL_TYPE_INTEGER,
203 		.name    = "Blue",
204 		.minimum = 0,
205 		.maximum = 3,
206 		.step    = 1,
207 #define BLUEBALANCE_DEF 1
208 		.default_value = BLUEBALANCE_DEF,
209 	    },
210 	    .set = sd_setbluebalance,
211 	    .get = sd_getbluebalance,
212 	},
213 	{
214 	    {
215 		.id      = V4L2_CID_GAIN,
216 		.type    = V4L2_CTRL_TYPE_INTEGER,
217 		.name    = "Gain",
218 		.minimum = 0,
219 #define GAIN_MAX 255
220 		.maximum = GAIN_MAX,
221 		.step    = 1,
222 #define GAIN_DEF 127
223 #define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
224 		.default_value = GAIN_DEF,
225 	    },
226 	    .set = sd_setgain,
227 	    .get = sd_getgain,
228 	},
229 	{
230 	    {
231 		.id      = V4L2_CID_EXPOSURE,
232 		.type    = V4L2_CTRL_TYPE_INTEGER,
233 		.name    = "Exposure",
234 		.minimum = 0,
235 		.maximum = 1023,
236 		.step    = 1,
237 #define EXPOSURE_DEF  66  /*  33 ms / 30 fps */
238 #define EXPOSURE_KNEE 133 /*  66 ms / 15 fps */
239 		.default_value = EXPOSURE_DEF,
240 	    },
241 	    .set = sd_setexposure,
242 	    .get = sd_getexposure,
243 	},
244 	{
245 	    {
246 		.id      = V4L2_CID_AUTOGAIN,
247 		.type    = V4L2_CTRL_TYPE_BOOLEAN,
248 		.name    = "Auto Gain",
249 		.minimum = 0,
250 		.maximum = 1,
251 		.step    = 1,
252 #define AUTOGAIN_DEF 1
253 		.default_value = AUTOGAIN_DEF,
254 	    },
255 	    .set = sd_setautogain,
256 	    .get = sd_getautogain,
257 	},
258 	{
259 	    {
260 		.id      = V4L2_CID_HFLIP,
261 		.type    = V4L2_CTRL_TYPE_BOOLEAN,
262 		.name    = "Mirror",
263 		.minimum = 0,
264 		.maximum = 1,
265 		.step    = 1,
266 #define HFLIP_DEF 0
267 		.default_value = HFLIP_DEF,
268 	    },
269 	    .set = sd_sethflip,
270 	    .get = sd_gethflip,
271 	},
272 	{
273 	    {
274 		.id      = V4L2_CID_VFLIP,
275 		.type    = V4L2_CTRL_TYPE_BOOLEAN,
276 		.name    = "Vflip",
277 		.minimum = 0,
278 		.maximum = 1,
279 		.step    = 1,
280 #define VFLIP_DEF 0
281 		.default_value = VFLIP_DEF,
282 	    },
283 	    .set = sd_setvflip,
284 	    .get = sd_getvflip,
285 	},
286 };
287 
288 static const struct v4l2_pix_format vga_mode[] = {
289 	{640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
290 		.bytesperline = 640,
291 		.sizeimage = 640 * 480 * 3 / 8 + 590,
292 		.colorspace = V4L2_COLORSPACE_JPEG,
293 		.priv = 0},
294 };
295 
296 #define LOAD_PAGE3		255
297 #define END_OF_SEQUENCE		0
298 
299 /* pac 7302 */
300 static const __u8 init_7302[] = {
301 /*	index,value */
302 	0xff, 0x01,		/* page 1 */
303 	0x78, 0x00,		/* deactivate */
304 	0xff, 0x01,
305 	0x78, 0x40,		/* led off */
306 };
307 static const __u8 start_7302[] = {
308 /*	index, len, [value]* */
309 	0xff, 1,	0x00,		/* page 0 */
310 	0x00, 12,	0x01, 0x40, 0x40, 0x40, 0x01, 0xe0, 0x02, 0x80,
311 			0x00, 0x00, 0x00, 0x00,
312 	0x0d, 24,	0x03, 0x01, 0x00, 0xb5, 0x07, 0xcb, 0x00, 0x00,
313 			0x07, 0xc8, 0x00, 0xea, 0x07, 0xcf, 0x07, 0xf7,
314 			0x07, 0x7e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x11,
315 	0x26, 2,	0xaa, 0xaa,
316 	0x2e, 1,	0x31,
317 	0x38, 1,	0x01,
318 	0x3a, 3,	0x14, 0xff, 0x5a,
319 	0x43, 11,	0x00, 0x0a, 0x18, 0x11, 0x01, 0x2c, 0x88, 0x11,
320 			0x00, 0x54, 0x11,
321 	0x55, 1,	0x00,
322 	0x62, 4, 	0x10, 0x1e, 0x1e, 0x18,
323 	0x6b, 1,	0x00,
324 	0x6e, 3,	0x08, 0x06, 0x00,
325 	0x72, 3,	0x00, 0xff, 0x00,
326 	0x7d, 23,	0x01, 0x01, 0x58, 0x46, 0x50, 0x3c, 0x50, 0x3c,
327 			0x54, 0x46, 0x54, 0x56, 0x52, 0x50, 0x52, 0x50,
328 			0x56, 0x64, 0xa4, 0x00, 0xda, 0x00, 0x00,
329 	0xa2, 10,	0x22, 0x2c, 0x3c, 0x54, 0x69, 0x7c, 0x9c, 0xb9,
330 			0xd2, 0xeb,
331 	0xaf, 1,	0x02,
332 	0xb5, 2,	0x08, 0x08,
333 	0xb8, 2,	0x08, 0x88,
334 	0xc4, 4,	0xae, 0x01, 0x04, 0x01,
335 	0xcc, 1,	0x00,
336 	0xd1, 11,	0x01, 0x30, 0x49, 0x5e, 0x6f, 0x7f, 0x8e, 0xa9,
337 			0xc1, 0xd7, 0xec,
338 	0xdc, 1,	0x01,
339 	0xff, 1,	0x01,		/* page 1 */
340 	0x12, 3,	0x02, 0x00, 0x01,
341 	0x3e, 2,	0x00, 0x00,
342 	0x76, 5,	0x01, 0x20, 0x40, 0x00, 0xf2,
343 	0x7c, 1,	0x00,
344 	0x7f, 10,	0x4b, 0x0f, 0x01, 0x2c, 0x02, 0x58, 0x03, 0x20,
345 			0x02, 0x00,
346 	0x96, 5,	0x01, 0x10, 0x04, 0x01, 0x04,
347 	0xc8, 14,	0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
348 			0x07, 0x00, 0x01, 0x07, 0x04, 0x01,
349 	0xd8, 1,	0x01,
350 	0xdb, 2,	0x00, 0x01,
351 	0xde, 7,	0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x00,
352 	0xe6, 4,	0x00, 0x00, 0x00, 0x01,
353 	0xeb, 1,	0x00,
354 	0xff, 1,	0x02,		/* page 2 */
355 	0x22, 1,	0x00,
356 	0xff, 1,	0x03,		/* page 3 */
357 	0, LOAD_PAGE3,			/* load the page 3 */
358 	0x11, 1,	0x01,
359 	0xff, 1,	0x02,		/* page 2 */
360 	0x13, 1,	0x00,
361 	0x22, 4,	0x1f, 0xa4, 0xf0, 0x96,
362 	0x27, 2,	0x14, 0x0c,
363 	0x2a, 5,	0xc8, 0x00, 0x18, 0x12, 0x22,
364 	0x64, 8,	0x00, 0x00, 0xf0, 0x01, 0x14, 0x44, 0x44, 0x44,
365 	0x6e, 1,	0x08,
366 	0xff, 1,	0x01,		/* page 1 */
367 	0x78, 1,	0x00,
368 	0, END_OF_SEQUENCE		/* end of sequence */
369 };
370 
371 #define SKIP		0xaa
372 /* page 3 - the value SKIP says skip the index - see reg_w_page() */
373 static const __u8 page3_7302[] = {
374 	0x90, 0x40, 0x03, 0x00, 0xc0, 0x01, 0x14, 0x16,
375 	0x14, 0x12, 0x00, 0x00, 0x00, 0x02, 0x33, 0x00,
376 	0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 	0x00, 0x00, 0x00, 0x47, 0x01, 0xb3, 0x01, 0x00,
378 	0x00, 0x08, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x21,
379 	0x00, 0x00, 0x00, 0x54, 0xf4, 0x02, 0x52, 0x54,
380 	0xa4, 0xb8, 0xe0, 0x2a, 0xf6, 0x00, 0x00, 0x00,
381 	0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382 	0x00, 0xfc, 0x00, 0xf2, 0x1f, 0x04, 0x00, 0x00,
383 	SKIP, 0x00, 0x00, 0xc0, 0xc0, 0x10, 0x00, 0x00,
384 	0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 	0x00, 0x40, 0xff, 0x03, 0x19, 0x00, 0x00, 0x00,
386 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387 	0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc8, 0xc8,
388 	0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
389 	0x08, 0x10, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00,
390 	0x01, 0x00, 0x02, 0x47, 0x00, 0x00, 0x00, 0x00,
391 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 	0x00, 0x02, 0xfa, 0x00, 0x64, 0x5a, 0x28, 0x00,
393 	0x00
394 };
395 
reg_w_buf(struct gspca_dev * gspca_dev,__u8 index,const u8 * buffer,int len)396 static void reg_w_buf(struct gspca_dev *gspca_dev,
397 		  __u8 index,
398 		  const u8 *buffer, int len)
399 {
400 	int ret;
401 
402 	if (gspca_dev->usb_err < 0)
403 		return;
404 	memcpy(gspca_dev->usb_buf, buffer, len);
405 	ret = usb_control_msg(gspca_dev->dev,
406 			usb_sndctrlpipe(gspca_dev->dev, 0),
407 			0,		/* request */
408 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
409 			0,		/* value */
410 			index, gspca_dev->usb_buf, len,
411 			500);
412 	if (ret < 0) {
413 		pr_err("reg_w_buf failed index 0x%02x, error %d\n",
414 		       index, ret);
415 		gspca_dev->usb_err = ret;
416 	}
417 }
418 
419 
reg_w(struct gspca_dev * gspca_dev,__u8 index,__u8 value)420 static void reg_w(struct gspca_dev *gspca_dev,
421 		  __u8 index,
422 		  __u8 value)
423 {
424 	int ret;
425 
426 	if (gspca_dev->usb_err < 0)
427 		return;
428 	gspca_dev->usb_buf[0] = value;
429 	ret = usb_control_msg(gspca_dev->dev,
430 			usb_sndctrlpipe(gspca_dev->dev, 0),
431 			0,			/* request */
432 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
433 			0, index, gspca_dev->usb_buf, 1,
434 			500);
435 	if (ret < 0) {
436 		pr_err("reg_w() failed index 0x%02x, value 0x%02x, error %d\n",
437 		       index, value, ret);
438 		gspca_dev->usb_err = ret;
439 	}
440 }
441 
reg_w_seq(struct gspca_dev * gspca_dev,const __u8 * seq,int len)442 static void reg_w_seq(struct gspca_dev *gspca_dev,
443 		const __u8 *seq, int len)
444 {
445 	while (--len >= 0) {
446 		reg_w(gspca_dev, seq[0], seq[1]);
447 		seq += 2;
448 	}
449 }
450 
451 /* load the beginning of a page */
reg_w_page(struct gspca_dev * gspca_dev,const __u8 * page,int len)452 static void reg_w_page(struct gspca_dev *gspca_dev,
453 			const __u8 *page, int len)
454 {
455 	int index;
456 	int ret = 0;
457 
458 	if (gspca_dev->usb_err < 0)
459 		return;
460 	for (index = 0; index < len; index++) {
461 		if (page[index] == SKIP)		/* skip this index */
462 			continue;
463 		gspca_dev->usb_buf[0] = page[index];
464 		ret = usb_control_msg(gspca_dev->dev,
465 				usb_sndctrlpipe(gspca_dev->dev, 0),
466 				0,			/* request */
467 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
468 				0, index, gspca_dev->usb_buf, 1,
469 				500);
470 		if (ret < 0) {
471 			pr_err("reg_w_page() failed index 0x%02x, value 0x%02x, error %d\n",
472 			       index, page[index], ret);
473 			gspca_dev->usb_err = ret;
474 			break;
475 		}
476 	}
477 }
478 
479 /* output a variable sequence */
reg_w_var(struct gspca_dev * gspca_dev,const __u8 * seq,const __u8 * page3,unsigned int page3_len)480 static void reg_w_var(struct gspca_dev *gspca_dev,
481 			const __u8 *seq,
482 			const __u8 *page3, unsigned int page3_len)
483 {
484 	int index, len;
485 
486 	for (;;) {
487 		index = *seq++;
488 		len = *seq++;
489 		switch (len) {
490 		case END_OF_SEQUENCE:
491 			return;
492 		case LOAD_PAGE3:
493 			reg_w_page(gspca_dev, page3, page3_len);
494 			break;
495 		default:
496 			if (len > USB_BUF_SZ) {
497 				PDEBUG(D_ERR|D_STREAM,
498 					"Incorrect variable sequence");
499 				return;
500 			}
501 			while (len > 0) {
502 				if (len < 8) {
503 					reg_w_buf(gspca_dev,
504 						index, seq, len);
505 					seq += len;
506 					break;
507 				}
508 				reg_w_buf(gspca_dev, index, seq, 8);
509 				seq += 8;
510 				index += 8;
511 				len -= 8;
512 			}
513 		}
514 	}
515 	/* not reached */
516 }
517 
518 /* this function is called at probe time for pac7302 */
sd_config(struct gspca_dev * gspca_dev,const struct usb_device_id * id)519 static int sd_config(struct gspca_dev *gspca_dev,
520 			const struct usb_device_id *id)
521 {
522 	struct sd *sd = (struct sd *) gspca_dev;
523 	struct cam *cam;
524 
525 	cam = &gspca_dev->cam;
526 
527 	PDEBUG(D_CONF, "Find Sensor PAC7302");
528 	cam->cam_mode = vga_mode;	/* only 640x480 */
529 	cam->nmodes = ARRAY_SIZE(vga_mode);
530 
531 	sd->brightness = BRIGHTNESS_DEF;
532 	sd->contrast = CONTRAST_DEF;
533 	sd->colors = COLOR_DEF;
534 	sd->white_balance = WHITEBALANCE_DEF;
535 	sd->red_balance = REDBALANCE_DEF;
536 	sd->blue_balance = BLUEBALANCE_DEF;
537 	sd->gain = GAIN_DEF;
538 	sd->exposure = EXPOSURE_DEF;
539 	sd->autogain = AUTOGAIN_DEF;
540 	sd->hflip = HFLIP_DEF;
541 	sd->vflip = VFLIP_DEF;
542 	sd->flags = id->driver_info;
543 	return 0;
544 }
545 
546 /* This function is used by pac7302 only */
setbrightcont(struct gspca_dev * gspca_dev)547 static void setbrightcont(struct gspca_dev *gspca_dev)
548 {
549 	struct sd *sd = (struct sd *) gspca_dev;
550 	int i, v;
551 	static const __u8 max[10] =
552 		{0x29, 0x33, 0x42, 0x5a, 0x6e, 0x80, 0x9f, 0xbb,
553 		 0xd4, 0xec};
554 	static const __u8 delta[10] =
555 		{0x35, 0x33, 0x33, 0x2f, 0x2a, 0x25, 0x1e, 0x17,
556 		 0x11, 0x0b};
557 
558 	reg_w(gspca_dev, 0xff, 0x00);		/* page 0 */
559 	for (i = 0; i < 10; i++) {
560 		v = max[i];
561 		v += (sd->brightness - BRIGHTNESS_MAX)
562 			* 150 / BRIGHTNESS_MAX;		/* 200 ? */
563 		v -= delta[i] * sd->contrast / CONTRAST_MAX;
564 		if (v < 0)
565 			v = 0;
566 		else if (v > 0xff)
567 			v = 0xff;
568 		reg_w(gspca_dev, 0xa2 + i, v);
569 	}
570 	reg_w(gspca_dev, 0xdc, 0x01);
571 }
572 
573 /* This function is used by pac7302 only */
setcolors(struct gspca_dev * gspca_dev)574 static void setcolors(struct gspca_dev *gspca_dev)
575 {
576 	struct sd *sd = (struct sd *) gspca_dev;
577 	int i, v;
578 	static const int a[9] =
579 		{217, -212, 0, -101, 170, -67, -38, -315, 355};
580 	static const int b[9] =
581 		{19, 106, 0, 19, 106, 1, 19, 106, 1};
582 
583 	reg_w(gspca_dev, 0xff, 0x03);			/* page 3 */
584 	reg_w(gspca_dev, 0x11, 0x01);
585 	reg_w(gspca_dev, 0xff, 0x00);			/* page 0 */
586 	for (i = 0; i < 9; i++) {
587 		v = a[i] * sd->colors / COLOR_MAX + b[i];
588 		reg_w(gspca_dev, 0x0f + 2 * i, (v >> 8) & 0x07);
589 		reg_w(gspca_dev, 0x0f + 2 * i + 1, v);
590 	}
591 	reg_w(gspca_dev, 0xdc, 0x01);
592 	PDEBUG(D_CONF|D_STREAM, "color: %i", sd->colors);
593 }
594 
setwhitebalance(struct gspca_dev * gspca_dev)595 static void setwhitebalance(struct gspca_dev *gspca_dev)
596 {
597 	struct sd *sd = (struct sd *) gspca_dev;
598 
599 	reg_w(gspca_dev, 0xff, 0x00);		/* page 0 */
600 	reg_w(gspca_dev, 0xc6, sd->white_balance);
601 
602 	reg_w(gspca_dev, 0xdc, 0x01);
603 	PDEBUG(D_CONF|D_STREAM, "white_balance: %i", sd->white_balance);
604 }
605 
setredbalance(struct gspca_dev * gspca_dev)606 static void setredbalance(struct gspca_dev *gspca_dev)
607 {
608 	struct sd *sd = (struct sd *) gspca_dev;
609 
610 	reg_w(gspca_dev, 0xff, 0x00);		/* page 0 */
611 	reg_w(gspca_dev, 0xc5, sd->red_balance);
612 
613 	reg_w(gspca_dev, 0xdc, 0x01);
614 	PDEBUG(D_CONF|D_STREAM, "red_balance: %i", sd->red_balance);
615 }
616 
setbluebalance(struct gspca_dev * gspca_dev)617 static void setbluebalance(struct gspca_dev *gspca_dev)
618 {
619 	struct sd *sd = (struct sd *) gspca_dev;
620 
621 	reg_w(gspca_dev, 0xff, 0x00);			/* page 0 */
622 	reg_w(gspca_dev, 0xc7, sd->blue_balance);
623 
624 	reg_w(gspca_dev, 0xdc, 0x01);
625 	PDEBUG(D_CONF|D_STREAM, "blue_balance: %i", sd->blue_balance);
626 }
627 
setgain(struct gspca_dev * gspca_dev)628 static void setgain(struct gspca_dev *gspca_dev)
629 {
630 	struct sd *sd = (struct sd *) gspca_dev;
631 
632 	reg_w(gspca_dev, 0xff, 0x03);			/* page 3 */
633 	reg_w(gspca_dev, 0x10, sd->gain >> 3);
634 
635 	/* load registers to sensor (Bit 0, auto clear) */
636 	reg_w(gspca_dev, 0x11, 0x01);
637 }
638 
setexposure(struct gspca_dev * gspca_dev)639 static void setexposure(struct gspca_dev *gspca_dev)
640 {
641 	struct sd *sd = (struct sd *) gspca_dev;
642 	__u8 clockdiv;
643 	__u16 exposure;
644 
645 	/* register 2 of frame 3 contains the clock divider configuring the
646 	   no fps according to the formula: 90 / reg. sd->exposure is the
647 	   desired exposure time in 0.5 ms. */
648 	clockdiv = (90 * sd->exposure + 1999) / 2000;
649 
650 	/* Note clockdiv = 3 also works, but when running at 30 fps, depending
651 	   on the scene being recorded, the camera switches to another
652 	   quantization table for certain JPEG blocks, and we don't know how
653 	   to decompress these blocks. So we cap the framerate at 15 fps */
654 	if (clockdiv < 6)
655 		clockdiv = 6;
656 	else if (clockdiv > 63)
657 		clockdiv = 63;
658 
659 	/* reg2 MUST be a multiple of 3, except when between 6 and 12?
660 	   Always round up, otherwise we cannot get the desired frametime
661 	   using the partial frame time exposure control */
662 	if (clockdiv < 6 || clockdiv > 12)
663 		clockdiv = ((clockdiv + 2) / 3) * 3;
664 
665 	/* frame exposure time in ms = 1000 * clockdiv / 90    ->
666 	exposure = (sd->exposure / 2) * 448 / (1000 * clockdiv / 90) */
667 	exposure = (sd->exposure * 45 * 448) / (1000 * clockdiv);
668 	/* 0 = use full frametime, 448 = no exposure, reverse it */
669 	exposure = 448 - exposure;
670 
671 	reg_w(gspca_dev, 0xff, 0x03);			/* page 3 */
672 	reg_w(gspca_dev, 0x02, clockdiv);
673 	reg_w(gspca_dev, 0x0e, exposure & 0xff);
674 	reg_w(gspca_dev, 0x0f, exposure >> 8);
675 
676 	/* load registers to sensor (Bit 0, auto clear) */
677 	reg_w(gspca_dev, 0x11, 0x01);
678 }
679 
sethvflip(struct gspca_dev * gspca_dev)680 static void sethvflip(struct gspca_dev *gspca_dev)
681 {
682 	struct sd *sd = (struct sd *) gspca_dev;
683 	u8 data, hflip, vflip;
684 
685 	hflip = sd->hflip;
686 	if (sd->flags & FL_HFLIP)
687 		hflip = !hflip;
688 	vflip = sd->vflip;
689 	if (sd->flags & FL_VFLIP)
690 		vflip = !vflip;
691 
692 	reg_w(gspca_dev, 0xff, 0x03);			/* page 3 */
693 	data = (hflip ? 0x08 : 0x00) | (vflip ? 0x04 : 0x00);
694 	reg_w(gspca_dev, 0x21, data);
695 
696 	/* load registers to sensor (Bit 0, auto clear) */
697 	reg_w(gspca_dev, 0x11, 0x01);
698 }
699 
700 /* this function is called at probe and resume time for pac7302 */
sd_init(struct gspca_dev * gspca_dev)701 static int sd_init(struct gspca_dev *gspca_dev)
702 {
703 	reg_w_seq(gspca_dev, init_7302, sizeof(init_7302)/2);
704 	return gspca_dev->usb_err;
705 }
706 
sd_start(struct gspca_dev * gspca_dev)707 static int sd_start(struct gspca_dev *gspca_dev)
708 {
709 	struct sd *sd = (struct sd *) gspca_dev;
710 
711 	sd->sof_read = 0;
712 
713 	reg_w_var(gspca_dev, start_7302,
714 		page3_7302, sizeof(page3_7302));
715 	setbrightcont(gspca_dev);
716 	setcolors(gspca_dev);
717 	setwhitebalance(gspca_dev);
718 	setredbalance(gspca_dev);
719 	setbluebalance(gspca_dev);
720 	setgain(gspca_dev);
721 	setexposure(gspca_dev);
722 	sethvflip(gspca_dev);
723 
724 	/* only resolution 640x480 is supported for pac7302 */
725 
726 	sd->sof_read = 0;
727 	sd->autogain_ignore_frames = 0;
728 	atomic_set(&sd->avg_lum, -1);
729 
730 	/* start stream */
731 	reg_w(gspca_dev, 0xff, 0x01);
732 	reg_w(gspca_dev, 0x78, 0x01);
733 
734 	return gspca_dev->usb_err;
735 }
736 
sd_stopN(struct gspca_dev * gspca_dev)737 static void sd_stopN(struct gspca_dev *gspca_dev)
738 {
739 
740 	/* stop stream */
741 	reg_w(gspca_dev, 0xff, 0x01);
742 	reg_w(gspca_dev, 0x78, 0x00);
743 }
744 
745 /* called on streamoff with alt 0 and on disconnect for pac7302 */
sd_stop0(struct gspca_dev * gspca_dev)746 static void sd_stop0(struct gspca_dev *gspca_dev)
747 {
748 	if (!gspca_dev->present)
749 		return;
750 	reg_w(gspca_dev, 0xff, 0x01);
751 	reg_w(gspca_dev, 0x78, 0x40);
752 }
753 
754 /* Include pac common sof detection functions */
755 #include "pac_common.h"
756 
do_autogain(struct gspca_dev * gspca_dev)757 static void do_autogain(struct gspca_dev *gspca_dev)
758 {
759 	struct sd *sd = (struct sd *) gspca_dev;
760 	int avg_lum = atomic_read(&sd->avg_lum);
761 	int desired_lum;
762 	const int deadzone = 30;
763 
764 	if (avg_lum == -1)
765 		return;
766 
767 	desired_lum = 270 + sd->brightness;
768 
769 	if (sd->autogain_ignore_frames > 0)
770 		sd->autogain_ignore_frames--;
771 	else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
772 			deadzone, GAIN_KNEE, EXPOSURE_KNEE))
773 		sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
774 }
775 
776 /* JPEG header, part 1 */
777 static const unsigned char pac_jpeg_header1[] = {
778   0xff, 0xd8,		/* SOI: Start of Image */
779 
780   0xff, 0xc0,		/* SOF0: Start of Frame (Baseline DCT) */
781   0x00, 0x11,		/* length = 17 bytes (including this length field) */
782   0x08			/* Precision: 8 */
783   /* 2 bytes is placed here: number of image lines */
784   /* 2 bytes is placed here: samples per line */
785 };
786 
787 /* JPEG header, continued */
788 static const unsigned char pac_jpeg_header2[] = {
789   0x03,			/* Number of image components: 3 */
790   0x01, 0x21, 0x00,	/* ID=1, Subsampling 1x1, Quantization table: 0 */
791   0x02, 0x11, 0x01,	/* ID=2, Subsampling 2x1, Quantization table: 1 */
792   0x03, 0x11, 0x01,	/* ID=3, Subsampling 2x1, Quantization table: 1 */
793 
794   0xff, 0xda,		/* SOS: Start Of Scan */
795   0x00, 0x0c,		/* length = 12 bytes (including this length field) */
796   0x03,			/* number of components: 3 */
797   0x01, 0x00,		/* selector 1, table 0x00 */
798   0x02, 0x11,		/* selector 2, table 0x11 */
799   0x03, 0x11,		/* selector 3, table 0x11 */
800   0x00, 0x3f,		/* Spectral selection: 0 .. 63 */
801   0x00			/* Successive approximation: 0 */
802 };
803 
pac_start_frame(struct gspca_dev * gspca_dev,__u16 lines,__u16 samples_per_line)804 static void pac_start_frame(struct gspca_dev *gspca_dev,
805 		__u16 lines, __u16 samples_per_line)
806 {
807 	unsigned char tmpbuf[4];
808 
809 	gspca_frame_add(gspca_dev, FIRST_PACKET,
810 		pac_jpeg_header1, sizeof(pac_jpeg_header1));
811 
812 	tmpbuf[0] = lines >> 8;
813 	tmpbuf[1] = lines & 0xff;
814 	tmpbuf[2] = samples_per_line >> 8;
815 	tmpbuf[3] = samples_per_line & 0xff;
816 
817 	gspca_frame_add(gspca_dev, INTER_PACKET,
818 		tmpbuf, sizeof(tmpbuf));
819 	gspca_frame_add(gspca_dev, INTER_PACKET,
820 		pac_jpeg_header2, sizeof(pac_jpeg_header2));
821 }
822 
823 /* this function is run at interrupt level */
sd_pkt_scan(struct gspca_dev * gspca_dev,u8 * data,int len)824 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
825 			u8 *data,			/* isoc packet */
826 			int len)			/* iso packet length */
827 {
828 	struct sd *sd = (struct sd *) gspca_dev;
829 	u8 *image;
830 	unsigned char *sof;
831 
832 	sof = pac_find_sof(&sd->sof_read, data, len);
833 	if (sof) {
834 		int n, lum_offset, footer_length;
835 
836 		/* 6 bytes after the FF D9 EOF marker a number of lumination
837 		   bytes are send corresponding to different parts of the
838 		   image, the 14th and 15th byte after the EOF seem to
839 		   correspond to the center of the image */
840 		lum_offset = 61 + sizeof pac_sof_marker;
841 		footer_length = 74;
842 
843 		/* Finish decoding current frame */
844 		n = (sof - data) - (footer_length + sizeof pac_sof_marker);
845 		if (n < 0) {
846 			gspca_dev->image_len += n;
847 			n = 0;
848 		} else {
849 			gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
850 		}
851 
852 		image = gspca_dev->image;
853 		if (image != NULL
854 		 && image[gspca_dev->image_len - 2] == 0xff
855 		 && image[gspca_dev->image_len - 1] == 0xd9)
856 			gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
857 
858 		n = sof - data;
859 		len -= n;
860 		data = sof;
861 
862 		/* Get average lumination */
863 		if (gspca_dev->last_packet_type == LAST_PACKET &&
864 				n >= lum_offset)
865 			atomic_set(&sd->avg_lum, data[-lum_offset] +
866 						data[-lum_offset + 1]);
867 		else
868 			atomic_set(&sd->avg_lum, -1);
869 
870 		/* Start the new frame with the jpeg header */
871 		/* The PAC7302 has the image rotated 90 degrees */
872 		pac_start_frame(gspca_dev,
873 			gspca_dev->width, gspca_dev->height);
874 	}
875 	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
876 }
877 
sd_setbrightness(struct gspca_dev * gspca_dev,__s32 val)878 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
879 {
880 	struct sd *sd = (struct sd *) gspca_dev;
881 
882 	sd->brightness = val;
883 	if (gspca_dev->streaming)
884 		setbrightcont(gspca_dev);
885 	return gspca_dev->usb_err;
886 }
887 
sd_getbrightness(struct gspca_dev * gspca_dev,__s32 * val)888 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
889 {
890 	struct sd *sd = (struct sd *) gspca_dev;
891 
892 	*val = sd->brightness;
893 	return 0;
894 }
895 
sd_setcontrast(struct gspca_dev * gspca_dev,__s32 val)896 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
897 {
898 	struct sd *sd = (struct sd *) gspca_dev;
899 
900 	sd->contrast = val;
901 	if (gspca_dev->streaming)
902 		setbrightcont(gspca_dev);
903 	return gspca_dev->usb_err;
904 }
905 
sd_getcontrast(struct gspca_dev * gspca_dev,__s32 * val)906 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
907 {
908 	struct sd *sd = (struct sd *) gspca_dev;
909 
910 	*val = sd->contrast;
911 	return 0;
912 }
913 
sd_setcolors(struct gspca_dev * gspca_dev,__s32 val)914 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
915 {
916 	struct sd *sd = (struct sd *) gspca_dev;
917 
918 	sd->colors = val;
919 	if (gspca_dev->streaming)
920 		setcolors(gspca_dev);
921 	return gspca_dev->usb_err;
922 }
923 
sd_getcolors(struct gspca_dev * gspca_dev,__s32 * val)924 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
925 {
926 	struct sd *sd = (struct sd *) gspca_dev;
927 
928 	*val = sd->colors;
929 	return 0;
930 }
931 
sd_setwhitebalance(struct gspca_dev * gspca_dev,__s32 val)932 static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
933 {
934 	struct sd *sd = (struct sd *) gspca_dev;
935 
936 	sd->white_balance = val;
937 	if (gspca_dev->streaming)
938 		setwhitebalance(gspca_dev);
939 	return gspca_dev->usb_err;
940 }
941 
sd_getwhitebalance(struct gspca_dev * gspca_dev,__s32 * val)942 static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
943 {
944 	struct sd *sd = (struct sd *) gspca_dev;
945 
946 	*val = sd->white_balance;
947 	return 0;
948 }
949 
sd_setredbalance(struct gspca_dev * gspca_dev,__s32 val)950 static int sd_setredbalance(struct gspca_dev *gspca_dev, __s32 val)
951 {
952 	struct sd *sd = (struct sd *) gspca_dev;
953 
954 	sd->red_balance = val;
955 	if (gspca_dev->streaming)
956 		setredbalance(gspca_dev);
957 	return gspca_dev->usb_err;
958 }
959 
sd_getredbalance(struct gspca_dev * gspca_dev,__s32 * val)960 static int sd_getredbalance(struct gspca_dev *gspca_dev, __s32 *val)
961 {
962 	struct sd *sd = (struct sd *) gspca_dev;
963 
964 	*val = sd->red_balance;
965 	return 0;
966 }
967 
sd_setbluebalance(struct gspca_dev * gspca_dev,__s32 val)968 static int sd_setbluebalance(struct gspca_dev *gspca_dev, __s32 val)
969 {
970 	struct sd *sd = (struct sd *) gspca_dev;
971 
972 	sd->blue_balance = val;
973 	if (gspca_dev->streaming)
974 		setbluebalance(gspca_dev);
975 	return gspca_dev->usb_err;
976 }
977 
sd_getbluebalance(struct gspca_dev * gspca_dev,__s32 * val)978 static int sd_getbluebalance(struct gspca_dev *gspca_dev, __s32 *val)
979 {
980 	struct sd *sd = (struct sd *) gspca_dev;
981 
982 	*val = sd->blue_balance;
983 	return 0;
984 }
985 
sd_setgain(struct gspca_dev * gspca_dev,__s32 val)986 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
987 {
988 	struct sd *sd = (struct sd *) gspca_dev;
989 
990 	sd->gain = val;
991 	if (gspca_dev->streaming)
992 		setgain(gspca_dev);
993 	return gspca_dev->usb_err;
994 }
995 
sd_getgain(struct gspca_dev * gspca_dev,__s32 * val)996 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
997 {
998 	struct sd *sd = (struct sd *) gspca_dev;
999 
1000 	*val = sd->gain;
1001 	return 0;
1002 }
1003 
sd_setexposure(struct gspca_dev * gspca_dev,__s32 val)1004 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1005 {
1006 	struct sd *sd = (struct sd *) gspca_dev;
1007 
1008 	sd->exposure = val;
1009 	if (gspca_dev->streaming)
1010 		setexposure(gspca_dev);
1011 	return gspca_dev->usb_err;
1012 }
1013 
sd_getexposure(struct gspca_dev * gspca_dev,__s32 * val)1014 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1015 {
1016 	struct sd *sd = (struct sd *) gspca_dev;
1017 
1018 	*val = sd->exposure;
1019 	return 0;
1020 }
1021 
sd_setautogain(struct gspca_dev * gspca_dev,__s32 val)1022 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1023 {
1024 	struct sd *sd = (struct sd *) gspca_dev;
1025 
1026 	sd->autogain = val;
1027 	/* when switching to autogain set defaults to make sure
1028 	   we are on a valid point of the autogain gain /
1029 	   exposure knee graph, and give this change time to
1030 	   take effect before doing autogain. */
1031 	if (sd->autogain) {
1032 		sd->exposure = EXPOSURE_DEF;
1033 		sd->gain = GAIN_DEF;
1034 		if (gspca_dev->streaming) {
1035 			sd->autogain_ignore_frames =
1036 				PAC_AUTOGAIN_IGNORE_FRAMES;
1037 			setexposure(gspca_dev);
1038 			setgain(gspca_dev);
1039 		}
1040 	}
1041 
1042 	return gspca_dev->usb_err;
1043 }
1044 
sd_getautogain(struct gspca_dev * gspca_dev,__s32 * val)1045 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1046 {
1047 	struct sd *sd = (struct sd *) gspca_dev;
1048 
1049 	*val = sd->autogain;
1050 	return 0;
1051 }
1052 
sd_sethflip(struct gspca_dev * gspca_dev,__s32 val)1053 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
1054 {
1055 	struct sd *sd = (struct sd *) gspca_dev;
1056 
1057 	sd->hflip = val;
1058 	if (gspca_dev->streaming)
1059 		sethvflip(gspca_dev);
1060 	return gspca_dev->usb_err;
1061 }
1062 
sd_gethflip(struct gspca_dev * gspca_dev,__s32 * val)1063 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
1064 {
1065 	struct sd *sd = (struct sd *) gspca_dev;
1066 
1067 	*val = sd->hflip;
1068 	return 0;
1069 }
1070 
sd_setvflip(struct gspca_dev * gspca_dev,__s32 val)1071 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1072 {
1073 	struct sd *sd = (struct sd *) gspca_dev;
1074 
1075 	sd->vflip = val;
1076 	if (gspca_dev->streaming)
1077 		sethvflip(gspca_dev);
1078 	return gspca_dev->usb_err;
1079 }
1080 
sd_getvflip(struct gspca_dev * gspca_dev,__s32 * val)1081 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1082 {
1083 	struct sd *sd = (struct sd *) gspca_dev;
1084 
1085 	*val = sd->vflip;
1086 	return 0;
1087 }
1088 
1089 #ifdef CONFIG_VIDEO_ADV_DEBUG
sd_dbg_s_register(struct gspca_dev * gspca_dev,struct v4l2_dbg_register * reg)1090 static int sd_dbg_s_register(struct gspca_dev *gspca_dev,
1091 			struct v4l2_dbg_register *reg)
1092 {
1093 	__u8 index;
1094 	__u8 value;
1095 
1096 	/* reg->reg: bit0..15: reserved for register index (wIndex is 16bit
1097 			       long on the USB bus)
1098 	*/
1099 	if (reg->match.type == V4L2_CHIP_MATCH_HOST &&
1100 	    reg->match.addr == 0 &&
1101 	    (reg->reg < 0x000000ff) &&
1102 	    (reg->val <= 0x000000ff)
1103 	) {
1104 		/* Currently writing to page 0 is only supported. */
1105 		/* reg_w() only supports 8bit index */
1106 		index = reg->reg & 0x000000ff;
1107 		value = reg->val & 0x000000ff;
1108 
1109 		/* Note that there shall be no access to other page
1110 		   by any other function between the page swith and
1111 		   the actual register write */
1112 		reg_w(gspca_dev, 0xff, 0x00);		/* page 0 */
1113 		reg_w(gspca_dev, index, value);
1114 
1115 		reg_w(gspca_dev, 0xdc, 0x01);
1116 	}
1117 	return gspca_dev->usb_err;
1118 }
1119 
sd_chip_ident(struct gspca_dev * gspca_dev,struct v4l2_dbg_chip_ident * chip)1120 static int sd_chip_ident(struct gspca_dev *gspca_dev,
1121 			struct v4l2_dbg_chip_ident *chip)
1122 {
1123 	int ret = -EINVAL;
1124 
1125 	if (chip->match.type == V4L2_CHIP_MATCH_HOST &&
1126 	    chip->match.addr == 0) {
1127 		chip->revision = 0;
1128 		chip->ident = V4L2_IDENT_UNKNOWN;
1129 		ret = 0;
1130 	}
1131 	return ret;
1132 }
1133 #endif
1134 
1135 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
sd_int_pkt_scan(struct gspca_dev * gspca_dev,u8 * data,int len)1136 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
1137 			u8 *data,		/* interrupt packet data */
1138 			int len)		/* interrput packet length */
1139 {
1140 	int ret = -EINVAL;
1141 	u8 data0, data1;
1142 
1143 	if (len == 2) {
1144 		data0 = data[0];
1145 		data1 = data[1];
1146 		if ((data0 == 0x00 && data1 == 0x11) ||
1147 		    (data0 == 0x22 && data1 == 0x33) ||
1148 		    (data0 == 0x44 && data1 == 0x55) ||
1149 		    (data0 == 0x66 && data1 == 0x77) ||
1150 		    (data0 == 0x88 && data1 == 0x99) ||
1151 		    (data0 == 0xaa && data1 == 0xbb) ||
1152 		    (data0 == 0xcc && data1 == 0xdd) ||
1153 		    (data0 == 0xee && data1 == 0xff)) {
1154 			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
1155 			input_sync(gspca_dev->input_dev);
1156 			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1157 			input_sync(gspca_dev->input_dev);
1158 			ret = 0;
1159 		}
1160 	}
1161 
1162 	return ret;
1163 }
1164 #endif
1165 
1166 /* sub-driver description for pac7302 */
1167 static const struct sd_desc sd_desc = {
1168 	.name = MODULE_NAME,
1169 	.ctrls = sd_ctrls,
1170 	.nctrls = ARRAY_SIZE(sd_ctrls),
1171 	.config = sd_config,
1172 	.init = sd_init,
1173 	.start = sd_start,
1174 	.stopN = sd_stopN,
1175 	.stop0 = sd_stop0,
1176 	.pkt_scan = sd_pkt_scan,
1177 	.dq_callback = do_autogain,
1178 #ifdef CONFIG_VIDEO_ADV_DEBUG
1179 	.set_register = sd_dbg_s_register,
1180 	.get_chip_ident = sd_chip_ident,
1181 #endif
1182 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1183 	.int_pkt_scan = sd_int_pkt_scan,
1184 #endif
1185 };
1186 
1187 /* -- module initialisation -- */
1188 static const struct usb_device_id device_table[] = {
1189 	{USB_DEVICE(0x06f8, 0x3009)},
1190 	{USB_DEVICE(0x093a, 0x2620)},
1191 	{USB_DEVICE(0x093a, 0x2621)},
1192 	{USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
1193 	{USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
1194 	{USB_DEVICE(0x093a, 0x2625)},
1195 	{USB_DEVICE(0x093a, 0x2626)},
1196 	{USB_DEVICE(0x093a, 0x2628)},
1197 	{USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
1198 	{USB_DEVICE(0x093a, 0x262a)},
1199 	{USB_DEVICE(0x093a, 0x262c)},
1200 	{USB_DEVICE(0x145f, 0x013c)},
1201 	{}
1202 };
1203 MODULE_DEVICE_TABLE(usb, device_table);
1204 
1205 /* -- device connect -- */
sd_probe(struct usb_interface * intf,const struct usb_device_id * id)1206 static int sd_probe(struct usb_interface *intf,
1207 			const struct usb_device_id *id)
1208 {
1209 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1210 				THIS_MODULE);
1211 }
1212 
1213 static struct usb_driver sd_driver = {
1214 	.name = MODULE_NAME,
1215 	.id_table = device_table,
1216 	.probe = sd_probe,
1217 	.disconnect = gspca_disconnect,
1218 #ifdef CONFIG_PM
1219 	.suspend = gspca_suspend,
1220 	.resume = gspca_resume,
1221 #endif
1222 };
1223 
1224 module_usb_driver(sd_driver);
1225