pac7311.c revision 1966bc2a48f12d5d11c4fbe0880955cc4bfda0f9
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 *
24 * Register page 1:
25 *
26 * Address	Description
27 * 0x08		Unknown compressor related, must always be 8 except when not
28 *		in 640x480 resolution and page 4 reg 2 <= 3 then set it to 9 !
29 * 0x1b		Auto white balance related, bit 0 is AWB enable (inverted)
30 *		bits 345 seem to toggle per color gains on/off (inverted)
31 * 0x78		Global control, bit 6 controls the LED (inverted)
32 * 0x80		Compression balance, interesting settings:
33 *		0x01 Use this to allow the camera to switch to higher compr.
34 *		     on the fly. Needed to stay within bandwidth @ 640x480@30
35 *		0x1c From usb captures under Windows for 640x480
36 *		0x2a Values >= this switch the camera to a lower compression,
37 *		     using the same table for both luminance and chrominance.
38 *		     This gives a sharper picture. Usable only at 640x480@ <
39 *		     15 fps or 320x240 / 160x120. Note currently the driver
40 *		     does not use this as the quality gain is small and the
41 *		     generated JPG-s are only understood by v4l-utils >= 0.8.9
42 *		0x3f From usb captures under Windows for 320x240
43 *		0x69 From usb captures under Windows for 160x120
44 *
45 * Register page 4:
46 *
47 * Address	Description
48 * 0x02		Clock divider 2-63, fps =~ 60 / val. Must be a multiple of 3 on
49 *		the 7302, so one of 3, 6, 9, ..., except when between 6 and 12?
50 * 0x0f		Master gain 1-245, low value = high gain
51 * 0x10		Another gain 0-15, limited influence (1-2x gain I guess)
52 * 0x21		Bitfield: 0-1 unused, 2-3 vflip/hflip, 4-5 unknown, 6-7 unused
53 *		Note setting vflip disabled leads to a much lower image quality,
54 *		so we always vflip, and tell userspace to flip it back
55 * 0x27		Seems to toggle various gains on / off, Setting bit 7 seems to
56 *		completely disable the analog amplification block. Set to 0x68
57 *		for max gain, 0x14 for minimal gain.
58 */
59
60#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
61
62#define MODULE_NAME "pac7311"
63
64#include <linux/input.h>
65#include "gspca.h"
66/* Include pac common sof detection functions */
67#include "pac_common.h"
68
69#define PAC7311_GAIN_DEFAULT     122
70#define PAC7311_EXPOSURE_DEFAULT   3 /* 20 fps, avoid using high compr. */
71
72MODULE_AUTHOR("Thomas Kaiser thomas@kaiser-linux.li");
73MODULE_DESCRIPTION("Pixart PAC7311");
74MODULE_LICENSE("GPL");
75
76struct sd {
77	struct gspca_dev gspca_dev;		/* !! must be the first item */
78
79	struct v4l2_ctrl *contrast;
80	struct v4l2_ctrl *hflip;
81
82	u8 sof_read;
83	u8 autogain_ignore_frames;
84
85	atomic_t avg_lum;
86};
87
88static const struct v4l2_pix_format vga_mode[] = {
89	{160, 120, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
90		.bytesperline = 160,
91		.sizeimage = 160 * 120 * 3 / 8 + 590,
92		.colorspace = V4L2_COLORSPACE_JPEG,
93		.priv = 2},
94	{320, 240, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
95		.bytesperline = 320,
96		.sizeimage = 320 * 240 * 3 / 8 + 590,
97		.colorspace = V4L2_COLORSPACE_JPEG,
98		.priv = 1},
99	{640, 480, V4L2_PIX_FMT_PJPG, V4L2_FIELD_NONE,
100		.bytesperline = 640,
101		.sizeimage = 640 * 480 * 3 / 8 + 590,
102		.colorspace = V4L2_COLORSPACE_JPEG,
103		.priv = 0},
104};
105
106#define LOAD_PAGE4		254
107#define END_OF_SEQUENCE		0
108
109static const __u8 init_7311[] = {
110	0xff, 0x01,
111	0x78, 0x40,	/* Bit_0=start stream, Bit_6=LED */
112	0x78, 0x40,	/* Bit_0=start stream, Bit_6=LED */
113	0x78, 0x44,	/* Bit_0=start stream, Bit_6=LED */
114	0xff, 0x04,
115	0x27, 0x80,
116	0x28, 0xca,
117	0x29, 0x53,
118	0x2a, 0x0e,
119	0xff, 0x01,
120	0x3e, 0x20,
121};
122
123static const __u8 start_7311[] = {
124/*	index, len, [value]* */
125	0xff, 1,	0x01,		/* page 1 */
126	0x02, 43,	0x48, 0x0a, 0x40, 0x08, 0x00, 0x00, 0x08, 0x00,
127			0x06, 0xff, 0x11, 0xff, 0x5a, 0x30, 0x90, 0x4c,
128			0x00, 0x07, 0x00, 0x0a, 0x10, 0x00, 0xa0, 0x10,
129			0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00,
130			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131			0x00, 0x00, 0x00,
132	0x3e, 42,	0x00, 0x00, 0x78, 0x52, 0x4a, 0x52, 0x78, 0x6e,
133			0x48, 0x46, 0x48, 0x6e, 0x5f, 0x49, 0x42, 0x49,
134			0x5f, 0x5f, 0x49, 0x42, 0x49, 0x5f, 0x6e, 0x48,
135			0x46, 0x48, 0x6e, 0x78, 0x52, 0x4a, 0x52, 0x78,
136			0x00, 0x00, 0x09, 0x1b, 0x34, 0x49, 0x5c, 0x9b,
137			0xd0, 0xff,
138	0x78, 6,	0x44, 0x00, 0xf2, 0x01, 0x01, 0x80,
139	0x7f, 18,	0x2a, 0x1c, 0x00, 0xc8, 0x02, 0x58, 0x03, 0x84,
140			0x12, 0x00, 0x1a, 0x04, 0x08, 0x0c, 0x10, 0x14,
141			0x18, 0x20,
142	0x96, 3,	0x01, 0x08, 0x04,
143	0xa0, 4,	0x44, 0x44, 0x44, 0x04,
144	0xf0, 13,	0x01, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0x00,
145			0x3f, 0x00, 0x0a, 0x01, 0x00,
146	0xff, 1,	0x04,		/* page 4 */
147	0, LOAD_PAGE4,			/* load the page 4 */
148	0x11, 1,	0x01,
149	0, END_OF_SEQUENCE		/* end of sequence */
150};
151
152#define SKIP		0xaa
153/* page 4 - the value SKIP says skip the index - see reg_w_page() */
154static const __u8 page4_7311[] = {
155	SKIP, SKIP, 0x04, 0x54, 0x07, 0x2b, 0x09, 0x0f,
156	0x09, 0x00, SKIP, SKIP, 0x07, 0x00, 0x00, 0x62,
157	0x08, SKIP, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
158	0x00, 0x00, 0x00, 0x03, 0xa0, 0x01, 0xf4, SKIP,
159	SKIP, 0x00, 0x08, SKIP, 0x03, SKIP, 0x00, 0x68,
160	0xca, 0x10, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00,
161	0x23, 0x28, 0x04, 0x11, 0x00, 0x00
162};
163
164static void reg_w_buf(struct gspca_dev *gspca_dev,
165		  __u8 index,
166		  const u8 *buffer, int len)
167{
168	int ret;
169
170	if (gspca_dev->usb_err < 0)
171		return;
172	memcpy(gspca_dev->usb_buf, buffer, len);
173	ret = usb_control_msg(gspca_dev->dev,
174			usb_sndctrlpipe(gspca_dev->dev, 0),
175			0,		/* request */
176			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
177			0,		/* value */
178			index, gspca_dev->usb_buf, len,
179			500);
180	if (ret < 0) {
181		pr_err("reg_w_buf() failed index 0x%02x, error %d\n",
182		       index, ret);
183		gspca_dev->usb_err = ret;
184	}
185}
186
187
188static void reg_w(struct gspca_dev *gspca_dev,
189		  __u8 index,
190		  __u8 value)
191{
192	int ret;
193
194	if (gspca_dev->usb_err < 0)
195		return;
196	gspca_dev->usb_buf[0] = value;
197	ret = usb_control_msg(gspca_dev->dev,
198			usb_sndctrlpipe(gspca_dev->dev, 0),
199			0,			/* request */
200			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
201			0, index, gspca_dev->usb_buf, 1,
202			500);
203	if (ret < 0) {
204		pr_err("reg_w() failed index 0x%02x, value 0x%02x, error %d\n",
205		       index, value, ret);
206		gspca_dev->usb_err = ret;
207	}
208}
209
210static void reg_w_seq(struct gspca_dev *gspca_dev,
211		const __u8 *seq, int len)
212{
213	while (--len >= 0) {
214		reg_w(gspca_dev, seq[0], seq[1]);
215		seq += 2;
216	}
217}
218
219/* load the beginning of a page */
220static void reg_w_page(struct gspca_dev *gspca_dev,
221			const __u8 *page, int len)
222{
223	int index;
224	int ret = 0;
225
226	if (gspca_dev->usb_err < 0)
227		return;
228	for (index = 0; index < len; index++) {
229		if (page[index] == SKIP)		/* skip this index */
230			continue;
231		gspca_dev->usb_buf[0] = page[index];
232		ret = usb_control_msg(gspca_dev->dev,
233				usb_sndctrlpipe(gspca_dev->dev, 0),
234				0,			/* request */
235			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
236				0, index, gspca_dev->usb_buf, 1,
237				500);
238		if (ret < 0) {
239			pr_err("reg_w_page() failed index 0x%02x, value 0x%02x, error %d\n",
240			       index, page[index], ret);
241			gspca_dev->usb_err = ret;
242			break;
243		}
244	}
245}
246
247/* output a variable sequence */
248static void reg_w_var(struct gspca_dev *gspca_dev,
249			const __u8 *seq,
250			const __u8 *page4, unsigned int page4_len)
251{
252	int index, len;
253
254	for (;;) {
255		index = *seq++;
256		len = *seq++;
257		switch (len) {
258		case END_OF_SEQUENCE:
259			return;
260		case LOAD_PAGE4:
261			reg_w_page(gspca_dev, page4, page4_len);
262			break;
263		default:
264			if (len > USB_BUF_SZ) {
265				PERR("Incorrect variable sequence");
266				return;
267			}
268			while (len > 0) {
269				if (len < 8) {
270					reg_w_buf(gspca_dev,
271						index, seq, len);
272					seq += len;
273					break;
274				}
275				reg_w_buf(gspca_dev, index, seq, 8);
276				seq += 8;
277				index += 8;
278				len -= 8;
279			}
280		}
281	}
282	/* not reached */
283}
284
285/* this function is called at probe time for pac7311 */
286static int sd_config(struct gspca_dev *gspca_dev,
287			const struct usb_device_id *id)
288{
289	struct cam *cam = &gspca_dev->cam;
290
291	cam->cam_mode = vga_mode;
292	cam->nmodes = ARRAY_SIZE(vga_mode);
293	cam->input_flags = V4L2_IN_ST_VFLIP;
294
295	return 0;
296}
297
298static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
299{
300	reg_w(gspca_dev, 0xff, 0x04);
301	reg_w(gspca_dev, 0x10, val);
302	/* load registers to sensor (Bit 0, auto clear) */
303	reg_w(gspca_dev, 0x11, 0x01);
304}
305
306static void setgain(struct gspca_dev *gspca_dev, s32 val)
307{
308	reg_w(gspca_dev, 0xff, 0x04);			/* page 4 */
309	reg_w(gspca_dev, 0x0e, 0x00);
310	reg_w(gspca_dev, 0x0f, gspca_dev->gain->maximum - val + 1);
311
312	/* load registers to sensor (Bit 0, auto clear) */
313	reg_w(gspca_dev, 0x11, 0x01);
314}
315
316static void setexposure(struct gspca_dev *gspca_dev, s32 val)
317{
318	reg_w(gspca_dev, 0xff, 0x04);			/* page 4 */
319	reg_w(gspca_dev, 0x02, val);
320
321	/* load registers to sensor (Bit 0, auto clear) */
322	reg_w(gspca_dev, 0x11, 0x01);
323
324	/*
325	 * Page 1 register 8 must always be 0x08 except when not in
326	 *  640x480 mode and page 4 reg 2 <= 3 then it must be 9
327	 */
328	reg_w(gspca_dev, 0xff, 0x01);
329	if (gspca_dev->pixfmt.width != 640 && val <= 3)
330		reg_w(gspca_dev, 0x08, 0x09);
331	else
332		reg_w(gspca_dev, 0x08, 0x08);
333
334	/*
335	 * Page1 register 80 sets the compression balance, normally we
336	 * want / use 0x1c, but for 640x480@30fps we must allow the
337	 * camera to use higher compression or we may run out of
338	 * bandwidth.
339	 */
340	if (gspca_dev->pixfmt.width == 640 && val == 2)
341		reg_w(gspca_dev, 0x80, 0x01);
342	else
343		reg_w(gspca_dev, 0x80, 0x1c);
344
345	/* load registers to sensor (Bit 0, auto clear) */
346	reg_w(gspca_dev, 0x11, 0x01);
347}
348
349static void sethvflip(struct gspca_dev *gspca_dev, s32 hflip, s32 vflip)
350{
351	__u8 data;
352
353	reg_w(gspca_dev, 0xff, 0x04);			/* page 4 */
354	data = (hflip ? 0x04 : 0x00) |
355	       (vflip ? 0x08 : 0x00);
356	reg_w(gspca_dev, 0x21, data);
357
358	/* load registers to sensor (Bit 0, auto clear) */
359	reg_w(gspca_dev, 0x11, 0x01);
360}
361
362/* this function is called at probe and resume time for pac7311 */
363static int sd_init(struct gspca_dev *gspca_dev)
364{
365	reg_w_seq(gspca_dev, init_7311, sizeof(init_7311)/2);
366	return gspca_dev->usb_err;
367}
368
369static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
370{
371	struct gspca_dev *gspca_dev =
372		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
373	struct sd *sd = (struct sd *)gspca_dev;
374
375	gspca_dev->usb_err = 0;
376
377	if (ctrl->id == V4L2_CID_AUTOGAIN && ctrl->is_new && ctrl->val) {
378		/* when switching to autogain set defaults to make sure
379		   we are on a valid point of the autogain gain /
380		   exposure knee graph, and give this change time to
381		   take effect before doing autogain. */
382		gspca_dev->exposure->val    = PAC7311_EXPOSURE_DEFAULT;
383		gspca_dev->gain->val        = PAC7311_GAIN_DEFAULT;
384		sd->autogain_ignore_frames  = PAC_AUTOGAIN_IGNORE_FRAMES;
385	}
386
387	if (!gspca_dev->streaming)
388		return 0;
389
390	switch (ctrl->id) {
391	case V4L2_CID_CONTRAST:
392		setcontrast(gspca_dev, ctrl->val);
393		break;
394	case V4L2_CID_AUTOGAIN:
395		if (gspca_dev->exposure->is_new || (ctrl->is_new && ctrl->val))
396			setexposure(gspca_dev, gspca_dev->exposure->val);
397		if (gspca_dev->gain->is_new || (ctrl->is_new && ctrl->val))
398			setgain(gspca_dev, gspca_dev->gain->val);
399		break;
400	case V4L2_CID_HFLIP:
401		sethvflip(gspca_dev, sd->hflip->val, 1);
402		break;
403	default:
404		return -EINVAL;
405	}
406	return gspca_dev->usb_err;
407}
408
409static const struct v4l2_ctrl_ops sd_ctrl_ops = {
410	.s_ctrl = sd_s_ctrl,
411};
412
413/* this function is called at probe time */
414static int sd_init_controls(struct gspca_dev *gspca_dev)
415{
416	struct sd *sd = (struct sd *) gspca_dev;
417	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
418
419	gspca_dev->vdev.ctrl_handler = hdl;
420	v4l2_ctrl_handler_init(hdl, 5);
421
422	sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
423					V4L2_CID_CONTRAST, 0, 15, 1, 7);
424	gspca_dev->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
425					V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
426	gspca_dev->exposure = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
427					V4L2_CID_EXPOSURE, 2, 63, 1,
428					PAC7311_EXPOSURE_DEFAULT);
429	gspca_dev->gain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
430					V4L2_CID_GAIN, 0, 244, 1,
431					PAC7311_GAIN_DEFAULT);
432	sd->hflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
433		V4L2_CID_HFLIP, 0, 1, 1, 0);
434
435	if (hdl->error) {
436		pr_err("Could not initialize controls\n");
437		return hdl->error;
438	}
439
440	v4l2_ctrl_auto_cluster(3, &gspca_dev->autogain, 0, false);
441	return 0;
442}
443
444/* -- start the camera -- */
445static int sd_start(struct gspca_dev *gspca_dev)
446{
447	struct sd *sd = (struct sd *) gspca_dev;
448
449	sd->sof_read = 0;
450
451	reg_w_var(gspca_dev, start_7311,
452		page4_7311, sizeof(page4_7311));
453	setcontrast(gspca_dev, v4l2_ctrl_g_ctrl(sd->contrast));
454	setgain(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->gain));
455	setexposure(gspca_dev, v4l2_ctrl_g_ctrl(gspca_dev->exposure));
456	sethvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip), 1);
457
458	/* set correct resolution */
459	switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
460	case 2:					/* 160x120 */
461		reg_w(gspca_dev, 0xff, 0x01);
462		reg_w(gspca_dev, 0x17, 0x20);
463		reg_w(gspca_dev, 0x87, 0x10);
464		break;
465	case 1:					/* 320x240 */
466		reg_w(gspca_dev, 0xff, 0x01);
467		reg_w(gspca_dev, 0x17, 0x30);
468		reg_w(gspca_dev, 0x87, 0x11);
469		break;
470	case 0:					/* 640x480 */
471		reg_w(gspca_dev, 0xff, 0x01);
472		reg_w(gspca_dev, 0x17, 0x00);
473		reg_w(gspca_dev, 0x87, 0x12);
474		break;
475	}
476
477	sd->sof_read = 0;
478	sd->autogain_ignore_frames = 0;
479	atomic_set(&sd->avg_lum, -1);
480
481	/* start stream */
482	reg_w(gspca_dev, 0xff, 0x01);
483	reg_w(gspca_dev, 0x78, 0x05);
484
485	return gspca_dev->usb_err;
486}
487
488static void sd_stopN(struct gspca_dev *gspca_dev)
489{
490	reg_w(gspca_dev, 0xff, 0x04);
491	reg_w(gspca_dev, 0x27, 0x80);
492	reg_w(gspca_dev, 0x28, 0xca);
493	reg_w(gspca_dev, 0x29, 0x53);
494	reg_w(gspca_dev, 0x2a, 0x0e);
495	reg_w(gspca_dev, 0xff, 0x01);
496	reg_w(gspca_dev, 0x3e, 0x20);
497	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
498	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
499	reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
500}
501
502static void do_autogain(struct gspca_dev *gspca_dev)
503{
504	struct sd *sd = (struct sd *) gspca_dev;
505	int avg_lum = atomic_read(&sd->avg_lum);
506	int desired_lum, deadzone;
507
508	if (avg_lum == -1)
509		return;
510
511	desired_lum = 170;
512	deadzone = 20;
513
514	if (sd->autogain_ignore_frames > 0)
515		sd->autogain_ignore_frames--;
516	else if (gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
517						    desired_lum, deadzone))
518		sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
519}
520
521/* JPEG header, part 1 */
522static const unsigned char pac_jpeg_header1[] = {
523  0xff, 0xd8,		/* SOI: Start of Image */
524
525  0xff, 0xc0,		/* SOF0: Start of Frame (Baseline DCT) */
526  0x00, 0x11,		/* length = 17 bytes (including this length field) */
527  0x08			/* Precision: 8 */
528  /* 2 bytes is placed here: number of image lines */
529  /* 2 bytes is placed here: samples per line */
530};
531
532/* JPEG header, continued */
533static const unsigned char pac_jpeg_header2[] = {
534  0x03,			/* Number of image components: 3 */
535  0x01, 0x21, 0x00,	/* ID=1, Subsampling 1x1, Quantization table: 0 */
536  0x02, 0x11, 0x01,	/* ID=2, Subsampling 2x1, Quantization table: 1 */
537  0x03, 0x11, 0x01,	/* ID=3, Subsampling 2x1, Quantization table: 1 */
538
539  0xff, 0xda,		/* SOS: Start Of Scan */
540  0x00, 0x0c,		/* length = 12 bytes (including this length field) */
541  0x03,			/* number of components: 3 */
542  0x01, 0x00,		/* selector 1, table 0x00 */
543  0x02, 0x11,		/* selector 2, table 0x11 */
544  0x03, 0x11,		/* selector 3, table 0x11 */
545  0x00, 0x3f,		/* Spectral selection: 0 .. 63 */
546  0x00			/* Successive approximation: 0 */
547};
548
549static void pac_start_frame(struct gspca_dev *gspca_dev,
550		__u16 lines, __u16 samples_per_line)
551{
552	unsigned char tmpbuf[4];
553
554	gspca_frame_add(gspca_dev, FIRST_PACKET,
555		pac_jpeg_header1, sizeof(pac_jpeg_header1));
556
557	tmpbuf[0] = lines >> 8;
558	tmpbuf[1] = lines & 0xff;
559	tmpbuf[2] = samples_per_line >> 8;
560	tmpbuf[3] = samples_per_line & 0xff;
561
562	gspca_frame_add(gspca_dev, INTER_PACKET,
563		tmpbuf, sizeof(tmpbuf));
564	gspca_frame_add(gspca_dev, INTER_PACKET,
565		pac_jpeg_header2, sizeof(pac_jpeg_header2));
566}
567
568/* this function is run at interrupt level */
569static void sd_pkt_scan(struct gspca_dev *gspca_dev,
570			u8 *data,			/* isoc packet */
571			int len)			/* iso packet length */
572{
573	struct sd *sd = (struct sd *) gspca_dev;
574	u8 *image;
575	unsigned char *sof;
576
577	sof = pac_find_sof(gspca_dev, &sd->sof_read, data, len);
578	if (sof) {
579		int n, lum_offset, footer_length;
580
581		/*
582		 * 6 bytes after the FF D9 EOF marker a number of lumination
583		 * bytes are send corresponding to different parts of the
584		 * image, the 14th and 15th byte after the EOF seem to
585		 * correspond to the center of the image.
586		 */
587		lum_offset = 24 + sizeof pac_sof_marker;
588		footer_length = 26;
589
590		/* Finish decoding current frame */
591		n = (sof - data) - (footer_length + sizeof pac_sof_marker);
592		if (n < 0) {
593			gspca_dev->image_len += n;
594			n = 0;
595		} else {
596			gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
597		}
598		image = gspca_dev->image;
599		if (image != NULL
600		 && image[gspca_dev->image_len - 2] == 0xff
601		 && image[gspca_dev->image_len - 1] == 0xd9)
602			gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
603
604		n = sof - data;
605		len -= n;
606		data = sof;
607
608		/* Get average lumination */
609		if (gspca_dev->last_packet_type == LAST_PACKET &&
610				n >= lum_offset)
611			atomic_set(&sd->avg_lum, data[-lum_offset] +
612						data[-lum_offset + 1]);
613		else
614			atomic_set(&sd->avg_lum, -1);
615
616		/* Start the new frame with the jpeg header */
617		pac_start_frame(gspca_dev,
618			gspca_dev->pixfmt.height, gspca_dev->pixfmt.width);
619	}
620	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
621}
622
623#if IS_ENABLED(CONFIG_INPUT)
624static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
625			u8 *data,		/* interrupt packet data */
626			int len)		/* interrupt packet length */
627{
628	int ret = -EINVAL;
629	u8 data0, data1;
630
631	if (len == 2) {
632		data0 = data[0];
633		data1 = data[1];
634		if ((data0 == 0x00 && data1 == 0x11) ||
635		    (data0 == 0x22 && data1 == 0x33) ||
636		    (data0 == 0x44 && data1 == 0x55) ||
637		    (data0 == 0x66 && data1 == 0x77) ||
638		    (data0 == 0x88 && data1 == 0x99) ||
639		    (data0 == 0xaa && data1 == 0xbb) ||
640		    (data0 == 0xcc && data1 == 0xdd) ||
641		    (data0 == 0xee && data1 == 0xff)) {
642			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
643			input_sync(gspca_dev->input_dev);
644			input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
645			input_sync(gspca_dev->input_dev);
646			ret = 0;
647		}
648	}
649
650	return ret;
651}
652#endif
653
654static const struct sd_desc sd_desc = {
655	.name = MODULE_NAME,
656	.config = sd_config,
657	.init = sd_init,
658	.init_controls = sd_init_controls,
659	.start = sd_start,
660	.stopN = sd_stopN,
661	.pkt_scan = sd_pkt_scan,
662	.dq_callback = do_autogain,
663#if IS_ENABLED(CONFIG_INPUT)
664	.int_pkt_scan = sd_int_pkt_scan,
665#endif
666};
667
668/* -- module initialisation -- */
669static const struct usb_device_id device_table[] = {
670	{USB_DEVICE(0x093a, 0x2600)},
671	{USB_DEVICE(0x093a, 0x2601)},
672	{USB_DEVICE(0x093a, 0x2603)},
673	{USB_DEVICE(0x093a, 0x2608)},
674	{USB_DEVICE(0x093a, 0x260e)},
675	{USB_DEVICE(0x093a, 0x260f)},
676	{}
677};
678MODULE_DEVICE_TABLE(usb, device_table);
679
680/* -- device connect -- */
681static int sd_probe(struct usb_interface *intf,
682			const struct usb_device_id *id)
683{
684	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
685				THIS_MODULE);
686}
687
688static struct usb_driver sd_driver = {
689	.name = MODULE_NAME,
690	.id_table = device_table,
691	.probe = sd_probe,
692	.disconnect = gspca_disconnect,
693#ifdef CONFIG_PM
694	.suspend = gspca_suspend,
695	.resume = gspca_resume,
696	.reset_resume = gspca_resume,
697#endif
698};
699
700module_usb_driver(sd_driver);
701