1 /*
2  *		Pixart PAC7311 library
3  *		Copyright (C) 2005 Thomas Kaiser thomas@kaiser-linux.li
4  *
5  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 
22 /* Some documentation about various registers as determined by trial and error.
23    When the register addresses differ between the 7202 and the 7311 the 2
24    different addresses are written as 7302addr/7311addr, when one of the 2
25    addresses is a - sign that register description is not valid for the
26    matching IC.
27 
28    Register page 1:
29 
30    Address	Description
31    -/0x08	Unknown compressor related, must always be 8 except when not
32 		in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
33    -/0x1b	Auto white balance related, bit 0 is AWB enable (inverted)
34 		bits 345 seem to toggle per color gains on/off (inverted)
35    0x78		Global control, bit 6 controls the LED (inverted)
36    -/0x80	JPEG compression ratio ? Best not touched
37 
38    Register page 3/4:
39 
40    Address	Description
41    0x02		Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
42 		the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
43    -/0x0f	Master gain 1-245, low value = high gain
44    0x10/-	Master gain 0-31
45    -/0x10	Another gain 0-15, limited influence (1-2x gain I guess)
46    0x21		Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
47    -/0x27	Seems to toggle various gains on / off, Setting bit 7 seems to
48 		completely disable the analog amplification block. Set to 0x68
49 		for max gain, 0x14 for minimal gain.
50 */
51 
52 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
53 
54 #define MODULE_NAME "pac7311"
55 
56 #include <linux/input.h>
57 #include "gspca.h"
58 
59 MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
60 MODULE_DESCRIPTION("Pixart PAC7311");
61 MODULE_LICENSE("GPL");
62 
63 /* specific webcam descriptor for pac7311 */
64 struct sd {
65 	struct gspca_dev gspca_dev;		/* !! must be the first item */
66 
67 	unsigned char contrast;
68 	unsigned char gain;
69 	unsigned char exposure;
70 	unsigned char autogain;
71 	__u8 hflip;
72 	__u8 vflip;
73 
74 	u8 sof_read;
75 	u8 autogain_ignore_frames;
76 
77 	atomic_t avg_lum;
78 };
79 
80 /* V4L2 controls supported by the driver */
81 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
82 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
83 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
84 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
85 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
86 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
87 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
88 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
89 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
90 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
91 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
92 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
93 
94 static const struct ctrl sd_ctrls[] = {
95 /* This control is for both the 7302 and the 7311 */
96 	{
97 	    {
98 		.id      = V4L2_CID_CONTRAST,
99 		.type    = V4L2_CTRL_TYPE_INTEGER,
100 		.name    = "Contrast",
101 		.minimum = 0,
102 #define CONTRAST_MAX 255
103 		.maximum = CONTRAST_MAX,
104 		.step    = 1,
105 #define CONTRAST_DEF 127
106 		.default_value = CONTRAST_DEF,
107 	    },
108 	    .set = sd_setcontrast,
109 	    .get = sd_getcontrast,
110 	},
111 /* All controls below are for both the 7302 and the 7311 */
112 	{
113 	    {
114 		.id      = V4L2_CID_GAIN,
115 		.type    = V4L2_CTRL_TYPE_INTEGER,
116 		.name    = "Gain",
117 		.minimum = 0,
118 #define GAIN_MAX 255
119 		.maximum = GAIN_MAX,
120 		.step    = 1,
121 #define GAIN_DEF 127
122 #define GAIN_KNEE 255 /* Gain seems to cause little noise on the pac73xx */
123 		.default_value = GAIN_DEF,
124 	    },
125 	    .set = sd_setgain,
126 	    .get = sd_getgain,
127 	},
128 	{
129 	    {
130 		.id      = V4L2_CID_EXPOSURE,
131 		.type    = V4L2_CTRL_TYPE_INTEGER,
132 		.name    = "Exposure",
133 		.minimum = 0,
134 #define EXPOSURE_MAX 255
135 		.maximum = EXPOSURE_MAX,
136 		.step    = 1,
137 #define EXPOSURE_DEF  16 /*  32 ms / 30 fps */
138 #define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
139 		.default_value = EXPOSURE_DEF,
140 	    },
141 	    .set = sd_setexposure,
142 	    .get = sd_getexposure,
143 	},
144 	{
145 	    {
146 		.id      = V4L2_CID_AUTOGAIN,
147 		.type    = V4L2_CTRL_TYPE_BOOLEAN,
148 		.name    = "Auto Gain",
149 		.minimum = 0,
150 		.maximum = 1,
151 		.step    = 1,
152 #define AUTOGAIN_DEF 1
153 		.default_value = AUTOGAIN_DEF,
154 	    },
155 	    .set = sd_setautogain,
156 	    .get = sd_getautogain,
157 	},
158 	{
159 	    {
160 		.id      = V4L2_CID_HFLIP,
161 		.type    = V4L2_CTRL_TYPE_BOOLEAN,
162 		.name    = "Mirror",
163 		.minimum = 0,
164 		.maximum = 1,
165 		.step    = 1,
166 #define HFLIP_DEF 0
167 		.default_value = HFLIP_DEF,
168 	    },
169 	    .set = sd_sethflip,
170 	    .get = sd_gethflip,
171 	},
172 	{
173 	    {
174 		.id      = V4L2_CID_VFLIP,
175 		.type    = V4L2_CTRL_TYPE_BOOLEAN,
176 		.name    = "Vflip",
177 		.minimum = 0,
178 		.maximum = 1,
179 		.step    = 1,
180 #define VFLIP_DEF 0
181 		.default_value = VFLIP_DEF,
182 	    },
183 	    .set = sd_setvflip,
184 	    .get = sd_getvflip,
185 	},
186 };
187 
188 static const struct v4l2_pix_format vga_mode[] = {
189 	{160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
190 		.bytesperline = 160,
191 		.sizeimage = 160 * 120 * 3 / 8 + 590,
192 		.colorspace = V4L2_COLORSPACE_JPEG,
193 		.priv = 2},
194 	{320, 240, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
195 		.bytesperline = 320,
196 		.sizeimage = 320 * 240 * 3 / 8 + 590,
197 		.colorspace = V4L2_COLORSPACE_JPEG,
198 		.priv = 1},
199 	{640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
200 		.bytesperline = 640,
201 		.sizeimage = 640 * 480 * 3 / 8 + 590,
202 		.colorspace = V4L2_COLORSPACE_JPEG,
203 		.priv = 0},
204 };
205 
206 #define LOAD_PAGE4		254
207 #define END_OF_SEQUENCE		0
208 
209 /* pac 7311 */
210 static const __u8 init_7311[] = {
211 	0x78, 0x40,	/* Bit_0=start stream, Bit_6=LED */
212 	0x78, 0x40,	/* Bit_0=start stream, Bit_6=LED */
213 	0x78, 0x44,	/* Bit_0=start stream, Bit_6=LED */
214 	0xff, 0x04,
215 	0x27, 0x80,
216 	0x28, 0xca,
217 	0x29, 0x53,
218 	0x2a, 0x0e,
219 	0xff, 0x01,
220 	0x3e, 0x20,
221 };
222 
223 static const __u8 start_7311[] = {
224 /*	index, len, [value]* */
225 	0xff, 1,	0x01,		/* page 1 */
226 	0x02, 43,	0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00,
227 			0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c,
228 			0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10,
229 			0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00,
230 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
231 			0x00, 0x00, 0x00,
232 	0x3e, 42,	0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e,
233 			0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49,
234 			0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48,
235 			0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78,
236 			0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b,
237 			0xd0, 0xff,
238 	0x78, 6,	0x44, 0x00, 0xf2, 0x01, 0x01, 0x80,
239 	0x7f, 18,	0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84,
240 			0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14,
241 			0x18, 0x20,
242 	0x96, 3,	0x01, 0x08, 0x04,
243 	0xa0, 4,	0x44, 0x44, 0x44, 0x04,
244 	0xf0, 13,	0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
245 			0x3f, 0x00, 0x0a, 0x01, 0x00,
246 	0xff, 1,	0x04,		/* page 4 */
247 	0, LOAD_PAGE4,			/* load the page 4 */
248 	0x11, 1,	0x01,
249 	0, END_OF_SEQUENCE		/* end of sequence */
250 };
251 
252 #define SKIP		0xaa
253 /* page 4 - the value SKIP says skip the index - see reg_w_page() */
254 static const __u8 page4_7311[] = {
255 	SKIP, SKIP, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
256 	0x09, 0x00, SKIP, SKIP, 0x07, 0x00, 0x00, 0x62,
257 	0x08, SKIP, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
258 	0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, SKIP,
259 	SKIP, 0x00, 0x08, SKIP, 0x03, SKIP, 0x00, 0x68,
260 	0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
261 	0x23, 0x28, 0x04, 0x11, 0x00, 0x00
262 };
263 
reg_w_buf(struct gspca_dev * gspca_dev,__u8 index,const u8 * buffer,int len)264 static void reg_w_buf(struct gspca_dev *gspca_dev,
265 		  __u8 index,
266 		  const u8 *buffer, int len)
267 {
268 	int ret;
269 
270 	if (gspca_dev->usb_err < 0)
271 		return;
272 	memcpy(gspca_dev->usb_buf, buffer, len);
273 	ret = usb_control_msg(gspca_dev->dev,
274 			usb_sndctrlpipe(gspca_dev->dev, 0),
275 			0,		/* request */
276 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
277 			0,		/* value */
278 			index, gspca_dev->usb_buf, len,
279 			500);
280 	if (ret < 0) {
281 		pr_err("reg_w_buf() failed index 0x%02x, error %d\n",
282 		       index, ret);
283 		gspca_dev->usb_err = ret;
284 	}
285 }
286 
287 
reg_w(struct gspca_dev * gspca_dev,__u8 index,__u8 value)288 static void reg_w(struct gspca_dev *gspca_dev,
289 		  __u8 index,
290 		  __u8 value)
291 {
292 	int ret;
293 
294 	if (gspca_dev->usb_err < 0)
295 		return;
296 	gspca_dev->usb_buf[0] = value;
297 	ret = usb_control_msg(gspca_dev->dev,
298 			usb_sndctrlpipe(gspca_dev->dev, 0),
299 			0,			/* request */
300 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
301 			0, index, gspca_dev->usb_buf, 1,
302 			500);
303 	if (ret < 0) {
304 		pr_err("reg_w() failed index 0x%02x, value 0x%02x, error %d\n",
305 		       index, value, ret);
306 		gspca_dev->usb_err = ret;
307 	}
308 }
309 
reg_w_seq(struct gspca_dev * gspca_dev,const __u8 * seq,int len)310 static void reg_w_seq(struct gspca_dev *gspca_dev,
311 		const __u8 *seq, int len)
312 {
313 	while (--len >= 0) {
314 		reg_w(gspca_dev, seq[0], seq[1]);
315 		seq += 2;
316 	}
317 }
318 
319 /* load the beginning of a page */
reg_w_page(struct gspca_dev * gspca_dev,const __u8 * page,int len)320 static void reg_w_page(struct gspca_dev *gspca_dev,
321 			const __u8 *page, int len)
322 {
323 	int index;
324 	int ret = 0;
325 
326 	if (gspca_dev->usb_err < 0)
327 		return;
328 	for (index = 0; index < len; index++) {
329 		if (page[index] == SKIP)		/* skip this index */
330 			continue;
331 		gspca_dev->usb_buf[0] = page[index];
332 		ret = usb_control_msg(gspca_dev->dev,
333 				usb_sndctrlpipe(gspca_dev->dev, 0),
334 				0,			/* request */
335 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
336 				0, index, gspca_dev->usb_buf, 1,
337 				500);
338 		if (ret < 0) {
339 			pr_err("reg_w_page() failed index 0x%02x, value 0x%02x, error %d\n",
340 			       index, page[index], ret);
341 			gspca_dev->usb_err = ret;
342 			break;
343 		}
344 	}
345 }
346 
347 /* output a variable sequence */
reg_w_var(struct gspca_dev * gspca_dev,const __u8 * seq,const __u8 * page4,unsigned int page4_len)348 static void reg_w_var(struct gspca_dev *gspca_dev,
349 			const __u8 *seq,
350 			const __u8 *page4, unsigned int page4_len)
351 {
352 	int index, len;
353 
354 	for (;;) {
355 		index = *seq++;
356 		len = *seq++;
357 		switch (len) {
358 		case END_OF_SEQUENCE:
359 			return;
360 		case LOAD_PAGE4:
361 			reg_w_page(gspca_dev, page4, page4_len);
362 			break;
363 		default:
364 			if (len > USB_BUF_SZ) {
365 				PDEBUG(D_ERR|D_STREAM,
366 					"Incorrect variable sequence");
367 				return;
368 			}
369 			while (len > 0) {
370 				if (len < 8) {
371 					reg_w_buf(gspca_dev,
372 						index, seq, len);
373 					seq += len;
374 					break;
375 				}
376 				reg_w_buf(gspca_dev, index, seq, 8);
377 				seq += 8;
378 				index += 8;
379 				len -= 8;
380 			}
381 		}
382 	}
383 	/* not reached */
384 }
385 
386 /* this function is called at probe time for pac7311 */
sd_config(struct gspca_dev * gspca_dev,const struct usb_device_id * id)387 static int sd_config(struct gspca_dev *gspca_dev,
388 			const struct usb_device_id *id)
389 {
390 	struct sd *sd = (struct sd *) gspca_dev;
391 	struct cam *cam;
392 
393 	cam = &gspca_dev->cam;
394 
395 	PDEBUG(D_CONF, "Find Sensor PAC7311");
396 	cam->cam_mode = vga_mode;
397 	cam->nmodes = ARRAY_SIZE(vga_mode);
398 
399 	sd->contrast = CONTRAST_DEF;
400 	sd->gain = GAIN_DEF;
401 	sd->exposure = EXPOSURE_DEF;
402 	sd->autogain = AUTOGAIN_DEF;
403 	sd->hflip = HFLIP_DEF;
404 	sd->vflip = VFLIP_DEF;
405 	return 0;
406 }
407 
408 /* This function is used by pac7311 only */
setcontrast(struct gspca_dev * gspca_dev)409 static void setcontrast(struct gspca_dev *gspca_dev)
410 {
411 	struct sd *sd = (struct sd *) gspca_dev;
412 
413 	reg_w(gspca_dev, 0xff, 0x04);
414 	reg_w(gspca_dev, 0x10, sd->contrast >> 4);
415 	/* load registers to sensor (Bit 0, auto clear) */
416 	reg_w(gspca_dev, 0x11, 0x01);
417 }
418 
setgain(struct gspca_dev * gspca_dev)419 static void setgain(struct gspca_dev *gspca_dev)
420 {
421 	struct sd *sd = (struct sd *) gspca_dev;
422 	int gain = GAIN_MAX - sd->gain;
423 
424 	if (gain < 1)
425 		gain = 1;
426 	else if (gain > 245)
427 		gain = 245;
428 	reg_w(gspca_dev, 0xff, 0x04);			/* page 4 */
429 	reg_w(gspca_dev, 0x0e, 0x00);
430 	reg_w(gspca_dev, 0x0f, gain);
431 
432 	/* load registers to sensor (Bit 0, auto clear) */
433 	reg_w(gspca_dev, 0x11, 0x01);
434 }
435 
setexposure(struct gspca_dev * gspca_dev)436 static void setexposure(struct gspca_dev *gspca_dev)
437 {
438 	struct sd *sd = (struct sd *) gspca_dev;
439 	__u8 reg;
440 
441 	/* register 2 of frame 3/4 contains the clock divider configuring the
442 	   no fps according to the formula: 60 / reg. sd->exposure is the
443 	   desired exposure time in ms. */
444 	reg = 120 * sd->exposure / 1000;
445 	if (reg < 2)
446 		reg = 2;
447 	else if (reg > 63)
448 		reg = 63;
449 
450 	reg_w(gspca_dev, 0xff, 0x04);			/* page 4 */
451 	reg_w(gspca_dev, 0x02, reg);
452 
453 	/* Page 1 register 8 must always be 0x08 except when not in
454 	   640x480 mode and Page3/4 reg 2 <= 3 then it must be 9 */
455 	reg_w(gspca_dev, 0xff, 0x01);
456 	if (gspca_dev->cam.cam_mode[(int)gspca_dev->curr_mode].priv &&
457 			reg <= 3) {
458 		reg_w(gspca_dev, 0x08, 0x09);
459 	} else {
460 		reg_w(gspca_dev, 0x08, 0x08);
461 	}
462 
463 	/* load registers to sensor (Bit 0, auto clear) */
464 	reg_w(gspca_dev, 0x11, 0x01);
465 }
466 
sethvflip(struct gspca_dev * gspca_dev)467 static void sethvflip(struct gspca_dev *gspca_dev)
468 {
469 	struct sd *sd = (struct sd *) gspca_dev;
470 	__u8 data;
471 
472 	reg_w(gspca_dev, 0xff, 0x04);			/* page 4 */
473 	data = (sd->hflip ? 0x04 : 0x00) | (sd->vflip ? 0x08 : 0x00);
474 	reg_w(gspca_dev, 0x21, data);
475 
476 	/* load registers to sensor (Bit 0, auto clear) */
477 	reg_w(gspca_dev, 0x11, 0x01);
478 }
479 
480 /* this function is called at probe and resume time for pac7311 */
sd_init(struct gspca_dev * gspca_dev)481 static int sd_init(struct gspca_dev *gspca_dev)
482 {
483 	reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
484 	return gspca_dev->usb_err;
485 }
486 
sd_start(struct gspca_dev * gspca_dev)487 static int sd_start(struct gspca_dev *gspca_dev)
488 {
489 	struct sd *sd = (struct sd *) gspca_dev;
490 
491 	sd->sof_read = 0;
492 
493 	reg_w_var(gspca_dev, start_7311,
494 		page4_7311, sizeof(page4_7311));
495 	setcontrast(gspca_dev);
496 	setgain(gspca_dev);
497 	setexposure(gspca_dev);
498 	sethvflip(gspca_dev);
499 
500 	/* set correct resolution */
501 	switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
502 	case 2:					/* 160x120 pac7311 */
503 		reg_w(gspca_dev, 0xff, 0x01);
504 		reg_w(gspca_dev, 0x17, 0x20);
505 		reg_w(gspca_dev, 0x87, 0x10);
506 		break;
507 	case 1:					/* 320x240 pac7311 */
508 		reg_w(gspca_dev, 0xff, 0x01);
509 		reg_w(gspca_dev, 0x17, 0x30);
510 		reg_w(gspca_dev, 0x87, 0x11);
511 		break;
512 	case 0:					/* 640x480 */
513 		reg_w(gspca_dev, 0xff, 0x01);
514 		reg_w(gspca_dev, 0x17, 0x00);
515 		reg_w(gspca_dev, 0x87, 0x12);
516 		break;
517 	}
518 
519 	sd->sof_read = 0;
520 	sd->autogain_ignore_frames = 0;
521 	atomic_set(&sd->avg_lum, -1);
522 
523 	/* start stream */
524 	reg_w(gspca_dev, 0xff, 0x01);
525 	reg_w(gspca_dev, 0x78, 0x05);
526 
527 	return gspca_dev->usb_err;
528 }
529 
sd_stopN(struct gspca_dev * gspca_dev)530 static void sd_stopN(struct gspca_dev *gspca_dev)
531 {
532 	reg_w(gspca_dev, 0xff, 0x04);
533 	reg_w(gspca_dev, 0x27, 0x80);
534 	reg_w(gspca_dev, 0x28, 0xca);
535 	reg_w(gspca_dev, 0x29, 0x53);
536 	reg_w(gspca_dev, 0x2a, 0x0e);
537 	reg_w(gspca_dev, 0xff, 0x01);
538 	reg_w(gspca_dev, 0x3e, 0x20);
539 	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
540 	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
541 	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
542 }
543 
544 /* called on streamoff with alt 0 and on disconnect for 7311 */
sd_stop0(struct gspca_dev * gspca_dev)545 static void sd_stop0(struct gspca_dev *gspca_dev)
546 {
547 }
548 
549 /* Include pac common sof detection functions */
550 #include "pac_common.h"
551 
do_autogain(struct gspca_dev * gspca_dev)552 static void do_autogain(struct gspca_dev *gspca_dev)
553 {
554 	struct sd *sd = (struct sd *) gspca_dev;
555 	int avg_lum = atomic_read(&sd->avg_lum);
556 	int desired_lum, deadzone;
557 
558 	if (avg_lum == -1)
559 		return;
560 
561 	desired_lum = 200;
562 	deadzone = 20;
563 
564 	if (sd->autogain_ignore_frames > 0)
565 		sd->autogain_ignore_frames--;
566 	else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum, desired_lum,
567 			deadzone, GAIN_KNEE, EXPOSURE_KNEE))
568 		sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
569 }
570 
571 /* JPEG header, part 1 */
572 static const unsigned char pac_jpeg_header1[] = {
573   0xff, 0xd8,		/* SOI: Start of Image */
574 
575   0xff, 0xc0,		/* SOF0: Start of Frame (Baseline DCT) */
576   0x00, 0x11,		/* length = 17 bytes (including this length field) */
577   0x08			/* Precision: 8 */
578   /* 2 bytes is placed here: number of image lines */
579   /* 2 bytes is placed here: samples per line */
580 };
581 
582 /* JPEG header, continued */
583 static const unsigned char pac_jpeg_header2[] = {
584   0x03,			/* Number of image components: 3 */
585   0x01, 0x21, 0x00,	/* ID=1, Subsampling 1x1, Quantization table: 0 */
586   0x02, 0x11, 0x01,	/* ID=2, Subsampling 2x1, Quantization table: 1 */
587   0x03, 0x11, 0x01,	/* ID=3, Subsampling 2x1, Quantization table: 1 */
588 
589   0xff, 0xda,		/* SOS: Start Of Scan */
590   0x00, 0x0c,		/* length = 12 bytes (including this length field) */
591   0x03,			/* number of components: 3 */
592   0x01, 0x00,		/* selector 1, table 0x00 */
593   0x02, 0x11,		/* selector 2, table 0x11 */
594   0x03, 0x11,		/* selector 3, table 0x11 */
595   0x00, 0x3f,		/* Spectral selection: 0 .. 63 */
596   0x00			/* Successive approximation: 0 */
597 };
598 
pac_start_frame(struct gspca_dev * gspca_dev,__u16 lines,__u16 samples_per_line)599 static void pac_start_frame(struct gspca_dev *gspca_dev,
600 		__u16 lines, __u16 samples_per_line)
601 {
602 	unsigned char tmpbuf[4];
603 
604 	gspca_frame_add(gspca_dev, FIRST_PACKET,
605 		pac_jpeg_header1, sizeof(pac_jpeg_header1));
606 
607 	tmpbuf[0] = lines >> 8;
608 	tmpbuf[1] = lines & 0xff;
609 	tmpbuf[2] = samples_per_line >> 8;
610 	tmpbuf[3] = samples_per_line & 0xff;
611 
612 	gspca_frame_add(gspca_dev, INTER_PACKET,
613 		tmpbuf, sizeof(tmpbuf));
614 	gspca_frame_add(gspca_dev, INTER_PACKET,
615 		pac_jpeg_header2, sizeof(pac_jpeg_header2));
616 }
617 
618 /* this function is run at interrupt level */
sd_pkt_scan(struct gspca_dev * gspca_dev,u8 * data,int len)619 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
620 			u8 *data,			/* isoc packet */
621 			int len)			/* iso packet length */
622 {
623 	struct sd *sd = (struct sd *) gspca_dev;
624 	u8 *image;
625 	unsigned char *sof;
626 
627 	sof = pac_find_sof(&sd->sof_read, data, len);
628 	if (sof) {
629 		int n, lum_offset, footer_length;
630 
631 		/* 6 bytes after the FF D9 EOF marker a number of lumination
632 		   bytes are send corresponding to different parts of the
633 		   image, the 14th and 15th byte after the EOF seem to
634 		   correspond to the center of the image */
635 		lum_offset = 24 + sizeof pac_sof_marker;
636 		footer_length = 26;
637 
638 		/* Finish decoding current frame */
639 		n = (sof - data) - (footer_length + sizeof pac_sof_marker);
640 		if (n < 0) {
641 			gspca_dev->image_len += n;
642 			n = 0;
643 		} else {
644 			gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
645 		}
646 		image = gspca_dev->image;
647 		if (image != NULL
648 		 && image[gspca_dev->image_len - 2] == 0xff
649 		 && image[gspca_dev->image_len - 1] == 0xd9)
650 			gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
651 
652 		n = sof - data;
653 		len -= n;
654 		data = sof;
655 
656 		/* Get average lumination */
657 		if (gspca_dev->last_packet_type == LAST_PACKET &&
658 				n >= lum_offset)
659 			atomic_set(&sd->avg_lum, data[-lum_offset] +
660 						data[-lum_offset + 1]);
661 		else
662 			atomic_set(&sd->avg_lum, -1);
663 
664 		/* Start the new frame with the jpeg header */
665 		pac_start_frame(gspca_dev,
666 			gspca_dev->height, gspca_dev->width);
667 	}
668 	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
669 }
670 
sd_setcontrast(struct gspca_dev * gspca_dev,__s32 val)671 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
672 {
673 	struct sd *sd = (struct sd *) gspca_dev;
674 
675 	sd->contrast = val;
676 	if (gspca_dev->streaming)
677 		setcontrast(gspca_dev);
678 	return gspca_dev->usb_err;
679 }
680 
sd_getcontrast(struct gspca_dev * gspca_dev,__s32 * val)681 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
682 {
683 	struct sd *sd = (struct sd *) gspca_dev;
684 
685 	*val = sd->contrast;
686 	return 0;
687 }
688 
sd_setgain(struct gspca_dev * gspca_dev,__s32 val)689 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
690 {
691 	struct sd *sd = (struct sd *) gspca_dev;
692 
693 	sd->gain = val;
694 	if (gspca_dev->streaming)
695 		setgain(gspca_dev);
696 	return gspca_dev->usb_err;
697 }
698 
sd_getgain(struct gspca_dev * gspca_dev,__s32 * val)699 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
700 {
701 	struct sd *sd = (struct sd *) gspca_dev;
702 
703 	*val = sd->gain;
704 	return 0;
705 }
706 
sd_setexposure(struct gspca_dev * gspca_dev,__s32 val)707 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
708 {
709 	struct sd *sd = (struct sd *) gspca_dev;
710 
711 	sd->exposure = val;
712 	if (gspca_dev->streaming)
713 		setexposure(gspca_dev);
714 	return gspca_dev->usb_err;
715 }
716 
sd_getexposure(struct gspca_dev * gspca_dev,__s32 * val)717 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
718 {
719 	struct sd *sd = (struct sd *) gspca_dev;
720 
721 	*val = sd->exposure;
722 	return 0;
723 }
724 
sd_setautogain(struct gspca_dev * gspca_dev,__s32 val)725 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
726 {
727 	struct sd *sd = (struct sd *) gspca_dev;
728 
729 	sd->autogain = val;
730 	/* when switching to autogain set defaults to make sure
731 	   we are on a valid point of the autogain gain /
732 	   exposure knee graph, and give this change time to
733 	   take effect before doing autogain. */
734 	if (sd->autogain) {
735 		sd->exposure = EXPOSURE_DEF;
736 		sd->gain = GAIN_DEF;
737 		if (gspca_dev->streaming) {
738 			sd->autogain_ignore_frames =
739 				PAC_AUTOGAIN_IGNORE_FRAMES;
740 			setexposure(gspca_dev);
741 			setgain(gspca_dev);
742 		}
743 	}
744 
745 	return gspca_dev->usb_err;
746 }
747 
sd_getautogain(struct gspca_dev * gspca_dev,__s32 * val)748 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
749 {
750 	struct sd *sd = (struct sd *) gspca_dev;
751 
752 	*val = sd->autogain;
753 	return 0;
754 }
755 
sd_sethflip(struct gspca_dev * gspca_dev,__s32 val)756 static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
757 {
758 	struct sd *sd = (struct sd *) gspca_dev;
759 
760 	sd->hflip = val;
761 	if (gspca_dev->streaming)
762 		sethvflip(gspca_dev);
763 	return gspca_dev->usb_err;
764 }
765 
sd_gethflip(struct gspca_dev * gspca_dev,__s32 * val)766 static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
767 {
768 	struct sd *sd = (struct sd *) gspca_dev;
769 
770 	*val = sd->hflip;
771 	return 0;
772 }
773 
sd_setvflip(struct gspca_dev * gspca_dev,__s32 val)774 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
775 {
776 	struct sd *sd = (struct sd *) gspca_dev;
777 
778 	sd->vflip = val;
779 	if (gspca_dev->streaming)
780 		sethvflip(gspca_dev);
781 	return gspca_dev->usb_err;
782 }
783 
sd_getvflip(struct gspca_dev * gspca_dev,__s32 * val)784 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
785 {
786 	struct sd *sd = (struct sd *) gspca_dev;
787 
788 	*val = sd->vflip;
789 	return 0;
790 }
791 
792 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
sd_int_pkt_scan(struct gspca_dev * gspca_dev,u8 * data,int len)793 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
794 			u8 *data,		/* interrupt packet data */
795 			int len)		/* interrupt packet length */
796 {
797 	int ret = -EINVAL;
798 	u8 data0, data1;
799 
800 	if (len == 2) {
801 		data0 = data[0];
802 		data1 = data[1];
803 		if ((data0 == 0x00 && data1 == 0x11) ||
804 		    (data0 == 0x22 && data1 == 0x33) ||
805 		    (data0 == 0x44 && data1 == 0x55) ||
806 		    (data0 == 0x66 && data1 == 0x77) ||
807 		    (data0 == 0x88 && data1 == 0x99) ||
808 		    (data0 == 0xaa && data1 == 0xbb) ||
809 		    (data0 == 0xcc && data1 == 0xdd) ||
810 		    (data0 == 0xee && data1 == 0xff)) {
811 			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
812 			input_sync(gspca_dev->input_dev);
813 			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
814 			input_sync(gspca_dev->input_dev);
815 			ret = 0;
816 		}
817 	}
818 
819 	return ret;
820 }
821 #endif
822 
823 /* sub-driver description for pac7311 */
824 static const struct sd_desc sd_desc = {
825 	.name = MODULE_NAME,
826 	.ctrls = sd_ctrls,
827 	.nctrls = ARRAY_SIZE(sd_ctrls),
828 	.config = sd_config,
829 	.init = sd_init,
830 	.start = sd_start,
831 	.stopN = sd_stopN,
832 	.stop0 = sd_stop0,
833 	.pkt_scan = sd_pkt_scan,
834 	.dq_callback = do_autogain,
835 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
836 	.int_pkt_scan = sd_int_pkt_scan,
837 #endif
838 };
839 
840 /* -- module initialisation -- */
841 static const struct usb_device_id device_table[] = {
842 	{USB_DEVICE(0x093a, 0x2600)},
843 	{USB_DEVICE(0x093a, 0x2601)},
844 	{USB_DEVICE(0x093a, 0x2603)},
845 	{USB_DEVICE(0x093a, 0x2608)},
846 	{USB_DEVICE(0x093a, 0x260e)},
847 	{USB_DEVICE(0x093a, 0x260f)},
848 	{}
849 };
850 MODULE_DEVICE_TABLE(usb, device_table);
851 
852 /* -- device connect -- */
sd_probe(struct usb_interface * intf,const struct usb_device_id * id)853 static int sd_probe(struct usb_interface *intf,
854 			const struct usb_device_id *id)
855 {
856 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
857 				THIS_MODULE);
858 }
859 
860 static struct usb_driver sd_driver = {
861 	.name = MODULE_NAME,
862 	.id_table = device_table,
863 	.probe = sd_probe,
864 	.disconnect = gspca_disconnect,
865 #ifdef CONFIG_PM
866 	.suspend = gspca_suspend,
867 	.resume = gspca_resume,
868 #endif
869 };
870 
871 module_usb_driver(sd_driver);
872