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