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