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
59MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
60MODULE_DESCRIPTION("Pixart PAC7311");
61MODULE_LICENSE("GPL");
62
63/* specific webcam descriptor for pac7311 */
64struct 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 */
81static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
82static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
83static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
84static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
85static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val);
87static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
88static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
89static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
90static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
91static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
92static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
93
94static 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
188static 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 */
210static 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
223static 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() */
254static 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
264static 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
288static 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
310static 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 */
320static 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 */
348static 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 */
387static 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 */
409static 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
419static 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
436static 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
467static 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 */
481static 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
487static 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
530static 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 */
545static void sd_stop0(struct gspca_dev *gspca_dev)
546{
547}
548
549/* Include pac common sof detection functions */
550#include "pac_common.h"
551
552static 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 */
572static 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 */
583static 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
599static 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 */
619static 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
671static 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
681static 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
689static 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
699static 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
707static 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
717static 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
725static 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
748static 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
756static 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
766static 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
774static 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
784static 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)
793static 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 */
824static 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 -- */
841static 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};
850MODULE_DEVICE_TABLE(usb, device_table);
851
852/* -- device connect -- */
853static 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
860static 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
871module_usb_driver(sd_driver);
872